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
b6309e4e
Commit
b6309e4e
authored
May 11, 2019
by
Zac Wood
Browse files
Merge branch 'revert-
ea27d283
' into 'master'
Revert "Merge branch '44-instructor-search' into 'master'" See merge request
!49
parents
ea27d283
5ca634f2
Pipeline
#4315
passed with stage
in 3 minutes and 51 seconds
Changes
84
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
schedules/app/controllers/search_controller.rb
View file @
b6309e4e
...
...
@@ -2,57 +2,8 @@ class SearchController < ApplicationController
def
index
redirect_to
(
home_url
)
unless
params
[
:query
].
length
>
1
if
params
[
:query
].
casecmp
(
'god'
).
zero?
bell
=
Instructor
.
find_by_name
(
'Jonathan Bell'
)
redirect_to
(
instructor_url
(
bell
))
end
@instructors
=
nil
@courses
=
nil
/[[:alpha:]]{2,4} \d{3}/
.
match
(
params
[
:query
])
do
|
m
|
subj
,
num
=
m
[
0
].
split
(
' '
)
course
=
Course
.
find_by
(
subject:
subj
.
upcase
,
course_number:
num
)
redirect_to
(
course_url
(
course
))
unless
course
.
nil?
end
/[[:alpha:]]{2,4}/i
.
match
(
params
[
:query
])
do
|
m
|
@courses
=
Course
.
where
(
subject:
m
[
0
].
upcase
)
.
joins
(
:course_sections
)
.
merge
(
CourseSection
.
in_semester
(
@semester
))
.
uniq
if
@courses
.
empty?
@courses
=
Course
.
where
(
"(courses.title LIKE ?)"
,
"%
#{
params
[
:query
]
}
%"
)
.
joins
(
:course_sections
)
.
merge
(
CourseSection
.
in_semester
(
@semester
))
.
uniq
other
=
Course
.
where
(
"(courses.description LIKE ?)"
,
"%
#{
params
[
:query
]
}
%"
)
.
joins
(
:course_sections
)
.
merge
(
CourseSection
.
in_semester
(
@semester
))
.
uniq
@courses
=
[
*
@courses
,
*
other
].
uniq
@instructors
=
Instructor
.
named
(
params
[
:query
])
end
@courses
.
map!
do
|
c
|
c
.
serializable_hash
.
merge
(
url:
course_url
(
c
))
end
gon
.
courses
=
@courses
gon
.
instructors
=
@instructors
end
/[0-9]{5}/
.
match
(
params
[
:query
])
do
|
m
|
redirect_to
(
course_url
(
CourseSection
.
latest_by_crn
(
m
[
0
]).
course
))
end
if
@courses
&
.
count
==
1
&&
@instructors
&
.
count
&
.
zero?
redirect_to
course_url
(
@courses
.
first
[
"id"
])
elsif
@courses
&
.
count
&
.
zero?
&&
@instructors
&
.
count
==
1
redirect_to
instructor_url
(
@instructors
.
first
)
end
results
=
SearchHelper
::
GenericItem
.
fetchall
(
String
.
new
(
params
[
:query
]),
semester:
@semester
).
group_by
(
&
:type
)
@instructors
=
results
[
:instructor
]
&
.
map
(
&
:data
)
@courses
=
results
[
:course
]
&
.
map
(
&
:data
)
end
end
schedules/app/helpers/about_helper.rb
deleted
100644 → 0
View file @
ea27d283
module
AboutHelper
end
schedules/app/helpers/course_sections_helper.rb
deleted
100644 → 0
View file @
ea27d283
module
CourseSectionsHelper
end
schedules/app/helpers/schedules_helper.rb
View file @
b6309e4e
...
...
@@ -19,9 +19,7 @@ module SchedulesHelper
{
title:
s
.
name
,
start:
"
#{
formatted_date
}
T
#{
time
}
"
,
end:
"
#{
formatted_date
}
T
#{
endtime
}
"
,
crn:
s
.
crn
,
active:
true
end:
"
#{
formatted_date
}
T
#{
endtime
}
"
}
end
end
.
flatten
...
...
schedules/app/helpers/search_helper.rb
View file @
b6309e4e
module
SearchHelper
def
in_cart?
(
crn
)
@cart
.
include?
crn
.
to_s
end
class
GenericQueryData
attr_reader
:semester
attr_reader
:sort_mode
...
...
schedules/app/javascript/jsconfig.json
deleted
100644 → 0
View file @
ea27d283
schedules/app/javascript/packs/application.js
View file @
b6309e4e
...
...
@@ -10,9 +10,6 @@
import
'
@babel/polyfill
'
;
import
'
url-polyfill
'
;
import
React
from
'
react
'
;
import
Cart
from
'
src/Cart
'
;
const
elementFromString
=
string
=>
{
const
html
=
new
DOMParser
().
parseFromString
(
string
,
'
text/html
'
);
return
html
.
body
.
firstChild
;
...
...
schedules/app/javascript/packs/home.js
deleted
100644 → 0
View file @
ea27d283
import
React
from
'
react
'
;
import
ReactDOM
from
'
react-dom
'
;
import
Cart
from
'
src/Cart
'
;
import
QuickAdd
from
'
src/QuickAdd
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
//const calendarUrl = `${window.location.protocol}//${window.location.hostname}${window.location.port == 3000 ? ':3000' : ''}/schedule`;
const
calendarUrl
=
'
/schedule
'
;
ReactDOM
.
render
(
<
QuickAdd
loadCalendar
=
{()
=>
{
window
.
location
.
href
=
calendarUrl
;
}}
/>
,
document
.
getElementById
(
'
quick-add
'
)
);
});
schedules/app/javascript/packs/instructor.js
deleted
100644 → 0
View file @
ea27d283
// /**
// * Either adds or removes a section from the cart depending on
// * if it is currently in the cart.
// */
import
$
from
'
jquery
'
;
import
Cart
from
'
src/Cart
'
;
const
addOrRemoveFromCart
=
async
(
event
,
sectionNode
)
=>
{
event
&&
event
.
stopPropagation
();
if
(
event
.
target
.
tagName
===
'
A
'
)
return
;
const
section
=
{
...
sectionNode
.
dataset
};
Cart
.
toggleCrn
(
section
.
crn
);
const
icon
=
$
(
sectionNode
.
querySelector
(
'
.add-remove-btn #icon
'
));
const
text
=
sectionNode
.
querySelector
(
'
.add-remove-btn .text
'
);
if
(
Cart
.
includesCrn
(
section
.
crn
))
{
icon
.
addClass
(
'
fa-minus
'
).
removeClass
(
'
fa-plus
'
);
text
.
innerText
=
'
Remove
'
;
}
else
{
icon
.
addClass
(
'
fa-plus
'
).
removeClass
(
'
fa-minus
'
);
text
.
innerText
=
'
Add
'
;
}
};
const
initSearchListeners
=
()
=>
{
const
sectionItems
=
Array
.
from
(
document
.
querySelectorAll
(
'
.section-item
'
));
sectionItems
.
forEach
(
item
=>
{
item
.
onclick
=
event
=>
addOrRemoveFromCart
(
event
,
item
);
});
setTimeout
(()
=>
{
sectionItems
.
forEach
(
item
=>
{
const
icon
=
$
(
item
.
querySelector
(
'
.add-remove-btn #icon
'
));
const
text
=
item
.
querySelector
(
'
.add-remove-btn .text
'
);
if
(
Cart
.
includesCrn
(
item
.
dataset
.
crn
))
{
icon
.
addClass
(
'
fa-minus
'
).
removeClass
(
'
fa-plus
'
);
text
.
innerText
=
'
Remove
'
;
}
else
{
icon
.
addClass
(
'
fa-plus
'
).
removeClass
(
'
fa-minus
'
);
text
.
innerText
=
'
Add
'
;
}
});
},
100
);
};
document
.
addEventListener
(
'
DOMContentLoaded
'
,
initSearchListeners
);
schedules/app/javascript/packs/schedules.js
View file @
b6309e4e
import
React
from
'
react
'
;
import
ReactDOM
from
'
react-dom
'
;
import
Cart
from
'
src/Cart
'
;
import
Cart
from
'
src/cart
'
;
import
{
saveAs
}
from
'
file-saver
'
;
import
html2canvas
from
'
html2canvas
'
;
import
$
from
'
jquery
'
;
import
CalendarPage
from
'
src/CalendarPage
'
;
import
'
fullcalendar
'
;
import
'
moment
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
ReactDOM
.
render
(
<
CalendarPage
/>
,
document
.
getElementById
(
'
root
'
));
const
eventsTemplate
=
document
.
querySelector
(
'
#events
'
);
if
(
eventsTemplate
)
{
const
eventsJSON
=
eventsTemplate
.
dataset
.
events
;
const
events
=
JSON
.
parse
(
eventsJSON
);
window
.
events
=
events
;
$
(
'
#calendar
'
).
fullCalendar
({
defaultDate
:
new
Date
(
2019
,
0
,
14
),
defaultView
:
'
agendaWeek
'
,
header
:
false
,
events
:
renderEvents
,
columnHeaderFormat
:
'
dddd
'
,
allDaySlot
:
false
,
});
}
initListeners
();
});
const
renderEvents
=
(
start
,
end
,
timezone
,
callback
)
=>
{
callback
(
window
.
events
);
};
const
remove
=
async
item
=>
{
await
Cart
.
toggleSection
({
...
item
.
dataset
});
location
.
reload
(
true
);
};
/**
* Generates a URL for the current sections in the schedule
* and sets the link in the modal to it.
*/
const
setUrlInModal
=
()
=>
{
document
.
getElementById
(
'
calendar-link
'
).
innerText
=
`
${
window
.
location
.
protocol
}
//
${
window
.
location
.
hostname
}
/api/schedules?crns=
${
Cart
.
_courses
.
join
(
'
,
'
)}
`
;
};
const
downloadIcs
=
async
()
=>
{
const
response
=
await
fetch
(
`
${
window
.
location
.
protocol
}
//
${
window
.
location
.
hostname
}
/api/schedules?crns=
${
Cart
.
_courses
.
join
(
'
,
'
)}
`
);
const
text
=
await
response
.
text
();
...
...
@@ -39,7 +69,7 @@ const initListeners = () => {
document
.
getElementById
(
'
save-image
'
).
onclick
=
saveImage
;
document
.
getElementById
(
'
share-url
'
).
innerText
=
`
${
window
.
location
.
protocol
}
//
${
window
.
location
.
hostname
}
/schedule/view?crns=
${
Cart
.
_courses
.
join
(
'
,
'
)}
`
;
document
.
getElementById
(
'
share-url
'
).
href
=
`
${
window
.
location
.
protocol
}
//
${
window
.
location
.
hostname
}
/schedule/view?crns=
${
Cart
.
_courses
.
join
(
'
,
'
)}
`
;
document
.
getElementById
(
'
share-url
'
).
href
=
`
${
window
.
location
.
protocol
}
//
${
window
.
location
.
hostname
}
/schedule/view?crns=
${
Cart
.
_courses
.
join
(
'
,
'
)}
`
;
};
if
(
!
HTMLCanvasElement
.
prototype
.
toBlob
)
{
...
...
schedules/app/javascript/packs/schedules_view.js
View file @
b6309e4e
import
Cart
from
'
src/
C
art
'
;
import
Cart
from
'
src/
c
art
'
;
import
{
saveAs
}
from
'
file-saver
'
;
import
html2canvas
from
'
html2canvas
'
;
import
$
from
'
jquery
'
;
...
...
schedules/app/javascript/packs/search.js
View file @
b6309e4e
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.
//
import Cart from 'src/cart';
import
Cart
from
'
src/cart
'
;
//
/**
// * Toggles the display of the schedule
// */
// const toggleSections = course => {
// const sections = course.querySelector('.sections');
//
const chev = $(course.querySelector('#course-chevron')
);
//
const
label = course.querySelector('#chevron-label')
;
/**
* Either adds or removes a section from the cart depending on
* if it is currently in the cart.
*/
const
addOrRemoveFromCart
=
async
(
event
,
sectionNode
)
=>
{
event
&&
event
.
stopPropagation
(
);
const
section
=
{
...
sectionNode
.
dataset
}
;
// if (sections.style.display === 'flex') {
// sections.style.display = 'none';
// chev.addClass('fa-chevron-down').removeClass('fa-chevron-up');
// label.innerText = 'Expand';
// } else {
// sections.style.display = 'flex';
// chev.addClass('fa-chevron-up').removeClass('fa-chevron-down');
// label.innerText = 'Minimize';
// }
// };
await
Cart
.
toggleSection
(
section
);
const
icon
=
$
(
sectionNode
.
querySelector
(
'
.add-remove-btn #icon
'
));
const
text
=
sectionNode
.
querySelector
(
'
.add-remove-btn .text
'
);
if
(
Cart
.
includesSection
(
section
))
{
icon
.
addClass
(
'
fa-minus
'
).
removeClass
(
'
fa-plus
'
);
text
.
innerText
=
'
Remove
'
;
}
else
{
icon
.
addClass
(
'
fa-plus
'
).
removeClass
(
'
fa-minus
'
);
text
.
innerText
=
'
Add
'
;
}
};
import
React
from
'
react
'
;
import
ReactDOM
from
'
react-dom
'
;
import
SearchList
from
'
src/SearchList
'
;
/**
* Toggles the display of the schedule
*/
const
toggleSections
=
course
=>
{
const
sections
=
course
.
querySelector
(
'
.sections
'
);
const
chev
=
$
(
course
.
querySelector
(
'
#course-chevron
'
));
const
label
=
course
.
querySelector
(
'
#chevron-label
'
);
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
ReactDOM
.
render
(
<
SearchList
courses
=
{
gon
.
courses
}
instructors
=
{
gon
.
instructors
}
/>, document.getElementById
(
'root'
))
;
});
if
(
sections
.
style
.
display
===
'
flex
'
)
{
sections
.
style
.
display
=
'
none
'
;
chev
.
addClass
(
'
fa-chevron-down
'
).
removeClass
(
'
fa-chevron-up
'
);
label
.
innerText
=
'
Expand
'
;
}
else
{
sections
.
style
.
display
=
'
flex
'
;
chev
.
addClass
(
'
fa-chevron-up
'
).
removeClass
(
'
fa-chevron-down
'
);
label
.
innerText
=
'
Minimize
'
;
}
};
const
initSearchListeners
=
()
=>
{
const
courseCards
=
Array
.
from
(
document
.
querySelectorAll
(
'
.course-card
'
));
courseCards
.
forEach
(
card
=>
{
card
.
onclick
=
()
=>
toggleSections
(
card
);
});
const
sectionItems
=
Array
.
from
(
document
.
querySelectorAll
(
'
.section-item
'
));
sectionItems
.
forEach
(
item
=>
(
item
.
onclick
=
event
=>
addOrRemoveFromCart
(
event
,
item
)));
};
document
.
addEventListener
(
'
DOMContentLoaded
'
,
initSearchListeners
);
schedules/app/javascript/src/Calendar.jsx
deleted
100644 → 0
View file @
ea27d283
import
React
from
'
react
'
;
import
BigCalendar
from
'
react-big-calendar
'
;
import
Toolbar
from
'
src/Toolbar
'
;
import
moment
from
'
moment
'
;
import
'
!style-loader!css-loader!react-big-calendar/lib/css/react-big-calendar.css
'
;
import
withSizes
from
'
react-sizes
'
;
const
localizer
=
BigCalendar
.
momentLocalizer
(
moment
);
const
Calendar
=
props
=>
(
<
div
className
=
"full-width"
style
=
{
{
backgroundColor
:
'
white
'
,
padding
:
'
24px
'
}
}
>
<
BigCalendar
localizer
=
{
localizer
}
events
=
{
props
.
events
}
title
=
""
components
=
{
{
toolbar
:
Toolbar
}
}
defaultView
=
"week"
views
=
{
[
'
week
'
,
'
day
'
]
}
startAccessor
=
"start"
endAccessor
=
"end"
defaultDate
=
{
moment
(
'
2019-01-14
'
).
toDate
()
}
formats
=
{
{
dayFormat
:
(
date
,
culture
,
localizer
)
=>
localizer
.
format
(
date
,
'
ddd
'
,
culture
),
dayHeaderFormat
:
(
date
,
culture
,
localizer
)
=>
localizer
.
format
(
date
,
'
ddd
'
,
culture
),
dayRangeHeaderFormat
:
()
=>
''
,
}
}
style
=
{
{
height
:
'
75vh
'
}
}
/>
</
div
>
);
export
default
Calendar
;
schedules/app/javascript/src/CalendarPage.jsx
deleted
100644 → 0
View file @
ea27d283
import
React
from
'
react
'
;
import
Calendar
from
'
src/Calendar
'
;
import
Cart
from
'
src/Cart
'
;
import
SectionList
from
'
src/SectionList
'
;
import
QuickAdd
from
'
src/QuickAdd
'
;
import
moment
from
'
moment
'
;
export
default
class
CalendarPage
extends
React
.
Component
{
state
=
{
events
:
[],
sections
:
[]
};
constructor
(
props
)
{
super
(
props
);
this
.
loadEvents
();
}
loadEvents
=
async
()
=>
{
const
response
=
await
fetch
(
`/schedule/events?crns=
${
Cart
.
crns
.
join
(
'
,
'
)}
`
);
const
json
=
await
response
.
json
();
this
.
setState
({
...
json
});
Cart
.
crns
=
json
.
sections
.
map
(
s
=>
s
.
crn
);
};
events
=
()
=>
{
return
this
.
state
.
events
.
filter
(
e
=>
e
.
active
).
map
(
e
=>
({
...
e
,
start
:
moment
(
e
.
start
).
toDate
(),
end
:
moment
(
e
.
end
).
toDate
()
}));
};
toggleSection
=
crn
=>
{
const
events
=
this
.
state
.
events
.
map
(
e
=>
({
...
e
,
active
:
e
.
crn
==
crn
?
!
e
.
active
:
e
.
active
}));
this
.
setState
({
events
});
};
removeAll
=
()
=>
{
Cart
.
crns
=
[];
location
.
reload
();
};
render
()
{
return
(
<
div
>
<
Calendar
events
=
{
this
.
events
()
}
/>
{
this
.
state
.
sections
.
length
>
0
?
(
<
div
className
=
"d-flex justify-content-between align-items-end"
>
<
h2
className
=
"mt-4"
>
Your Schedule
</
h2
>
{
'
'
}
<
button
type
=
"button"
onClick
=
{
this
.
removeAll
}
className
=
"btn btn-danger mb-8"
>
Remove all sections
</
button
>
</
div
>
)
:
null
}
<
SectionList
onClick
=
{
this
.
toggleSection
}
sections
=
{
this
.
state
.
sections
}
expanded
=
{
true
}
/>
<
QuickAdd
loadCalendar
=
{
this
.
loadEvents
}
/>
</
div
>
);
}
}
schedules/app/javascript/src/Chevron.jsx
deleted
100644 → 0
View file @
ea27d283
import
React
from
'
react
'
;
export
default
class
Chevron
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
}
render
()
{
const
base
=
{
display
:
'
block
'
,
textAlign
:
'
center
'
};
return
(
<
div
>
<
div
style
=
{
this
.
props
.
open
?
{
...
base
}
:
{
display
:
'
none
'
}
}
>
<
p
id
=
"chevron-label"
style
=
{
{
marginBottom
:
'
4px
'
,
fontSize
:
'
10px
'
}
}
>
Minimize
</
p
>
<
i
id
=
"course-chevron"
className
=
"fas fa-chevron-up"
/>
</
div
>
<
div
style
=
{
this
.
props
.
open
?
{
display
:
'
none
'
}
:
{
...
base
}
}
>
<
p
id
=
"chevron-label"
style
=
{
{
marginBottom
:
'
4px
'
,
fontSize
:
'
10px
'
}
}
>
Expand
</
p
>
<
i
id
=
"course-chevron"
className
=
"fas fa-chevron-down"
/>
</
div
>
</
div
>
);
}
}
schedules/app/javascript/src/Course.jsx
deleted
100644 → 0
View file @
ea27d283
import
React
from
'
react
'
;
import
SectionList
from
'
src/SectionList
'
;
export
default
class
Course
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
expanded
:
false
,
sections
:
[]
};
}
async
onClick
()
{
if
(
this
.
state
.
sections
.
length
===
0
)
{
const
resp
=
await
fetch
(
`/api/course_sections?course_id=
${
this
.
props
.
id
}
`
);
const
json
=
await
resp
.
json
();
this
.
setState
({
sections
:
json
});
}
this
.
setState
({
expanded
:
!
this
.
state
.
expanded
});
}
prereqs
=
()
=>
{
if
(
this
.
props
.
prereqs
)
{
const
[
first
,
rest
]
=
this
.
props
.
prereqs
.
split
(
'
:
'
);
const
[
reqs
,
note
]
=
rest
.
split
(
'
.
'
);
return
(
<
p
>
<
strong
>
{
first
}
</
strong
>
{
reqs
}
<
sub
>
{
note
}
</
sub
>
</
p
>
);
}
return
<
div
/>;
};
// <% first, rest = course.prereqs.split(':') %>
// <% prereqs, note = rest.split('.') %>
// <p><strong><%= first %>:</strong> <%= prereqs %> <sub><%= note %></sub></p>
render
()
{
const
{
id
,
subject
,
course_number
,
title
,
credits
,
description
,
url
}
=
this
.
props
;
return
(
<
div
className
=
"card course-card"
onClick
=
{
()
=>
this
.
onClick
()
}
>
<
div
className
=
"card-header"
>
<
div
className
=
"row"
>
<
div
className
=
"col"
>
<
a
href
=
{
url
}
>
<
h4
className
=
"title"
>
{
`
${
subject
}
${
course_number
}
`
}
</
h4
>
</
a
>
</
div
>
</
div
>
<
div
className
=
"d-md-flex justify-content-between"
>
<
h5
>
<
em
>
{
title
}
</
em
>
</
h5
>
<
div
className
=
"attr-list justify-content-start"
>
<
div
className
=
"attr"
>
<
div
className
=
"icon"
>
<
i
className
=
"fa fa-book"
/>
</
div
>
{
credits
}
credits
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className
=
"card-body"
>
<
p
>
{
description
}
</
p
>
{
this
.
prereqs
()
}
<
div
className
=
"list-group list-group-flush sections"
style
=
{
{
display
:
'
none
'
}
}
/>
<
SectionList
{
...
this
.
state
}
expandable
=
{
true
}
/>
</
div
>
</
div
>
);
}
}
schedules/app/javascript/src/CourseList.jsx
deleted
100644 → 0
View file @
ea27d283
import
React
from
'
react
'
;
import
Course
from
'
src/Course
'
;
export
default
class
CourseList
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
}
render
()
{
return
(
<
div
>
{
this
.
props
.
courses
.
map
(
course
=>
(
<
Course
key
=
{
course
.
id
}
{
...
course
}
/>
))
}
</
div
>
);
}
}
schedules/app/javascript/src/InstructorCard.jsx
deleted
100644 → 0
View file @
ea27d283
import
React
from
'
react
'
;
export
default
class
InstructorCard
extends
React
.
Component
{
render
()
{
const
inst
=
this
.
props
.
instructor
;
return
(
<
div
className
=
"card p-3"
>
<
span
>
<
i
className
=
"fas fa-chalkboard-teacher mr-2"
/>
<
a
href
=
{
`/instructors/
${
inst
.
id
}
`
}
>
{
this
.
props
.
instructor
.
name
}
</
a
>
</
span
>
</
div
>
);
}
}
schedules/app/javascript/src/InstructorList.jsx
deleted
100644 → 0
View file @
ea27d283
import
React
from
'
react
'
;
import
InstructorCard
from
'
src/InstructorCard
'
;
export
default
class
InstructorList
extends
React
.
Component
{
render
()
{
return
<
div
>
{
this
.
props
.
instructors
&&
this
.
props
.
instructors
.
map
(
i
=>
<
InstructorCard
instructor
=
{
i
}
/>)
}
</
div
>;
}
}
schedules/app/javascript/src/QuickAdd.jsx
deleted
100644 → 0
View file @
ea27d283
import
React
from
'
react
'
;
import
Cart
from
'
src/Cart
'
;
export
default
class
QuickAdd
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
crnString
:
''
};
}
add
=
e
=>
{
e
.
preventDefault
();
const
crns
=
this
.
state
.
crnString
.
split
(
'
,
'
);
crns
.
forEach
(
c
=>
c
.
length
===
5
&&
Cart
.
addCrn
(
c
));
this
.
props
.
loadCalendar
();
};
render
()
{
return
(
<
div
>
<
h3
className
=
"quick-add-header"
>
Quick add
</
h3
>
<
p
>
Want to quickly generate a calendar populated with your semester's classes? Enter the CRNs in a comma separated list below.
</
p
>
<
form
onSubmit
=
{
this
.
add
}
className
=
"form"
>