Skip to content

Instantly share code, notes, and snippets.

@bufordtaylor
Created September 8, 2015 23:52
Show Gist options
  • Save bufordtaylor/feb1d78921f98d9002f9 to your computer and use it in GitHub Desktop.
Save bufordtaylor/feb1d78921f98d9002f9 to your computer and use it in GitHub Desktop.
react example
@Welcome = React.createClass
propTypes:
q: React.PropTypes.string.isRequired
getInitialState: ->
didFetchData: false
projects: []
project_fav_ids: []
meta:
total_pages: 0
current_page: 1
total_count: 0
fetchData:
search: ''
page: 1
order: ''
paid: ''
componentDidMount: ->
@_fetchProjects({})
@_subscribeToEvents()
_fetchProjects: ()->
$.ajax
url: Routes.api_v1_welcome_path()
dataType: 'json'
data: @state.fetchData
.done @_fetchDataDone
.fail @_fetchDataFail
_fetchDataDone: (data, textStatus, jqXHR) ->
return false unless @isMounted()
@setState
didFetchData: true
projects: data.projects
project_fav_ids: data.project_fav_ids
meta: data.meta
_fetchDataFail: (xhr, status, err) =>
console.error @props.url, status, err.toString()
_subscribeToEvents: ->
PubSub.subscribe 'resetButton:onClick', ()=>
@state.fetchData.search = ''
@state.fetchData.page = 1
@_fetchProjects()
_unsubscribeFromEvents: ->
PubSub.unsubscribe 'resetButton:onClick'
_handleOnSearchSubmit: (search) ->
@state.fetchData.search = search
@state.fetchData.page = 1
@_fetchProjects()
_handleOnPaginate: (pageNumber) ->
@state.fetchData.page = pageNumber
@_fetchProjects()
_handleOnOrderChange: (e) ->
@state.fetchData.order = e.target.value
@_fetchProjects()
_handleOnPaidChange: (e) ->
@state.fetchData.paid = if e.target.checked then "t" else ""
@_fetchProjects()
render: ->
favs = @state.project_fav_ids
projectsNode = @state.projects.map (p) ->
<ProjectCell key={p.id} data={p} favs={favs} />
noDataNode =
<div className="row mt col-centered project-info-div">
<div className="col-md-12">
<div className="warning">
<span className="fa-stack">
<i className="fa fa-meh-o fa-stack-2x"></i>
</span>
<h4>No projects found...</h4>
</div>
</div>
</div>
<div>
<div className="row mt col-centered project-info-div">
<div className="col-md-12">
<ProjectSearch totalCount={@state.meta.total_entries} onFormSubmit={@_handleOnSearchSubmit}/>
<PaginatorSection totalPages={@state.meta.total_pages} currentPage={@state.meta.current_page} onPaginate={@_handleOnPaginate}/>
</div>
<div className="col-md-12">
Sort by "newest" is back
<span className="fa fa-arrow-right"> </span>
<ProjectOrderBy onChange={@_handleOnOrderChange}/>
<ProjectPaid onChange={@_handleOnPaidChange}/>
</div>
</div>
<div className="projects-wrapper">
{
if @state.projects.length > 0
{projectsNode}
else if @state.didFetchData
{noDataNode}
}
</div>
<PaginatorSection totalPages={@state.meta.total_pages} currentPage={@state.meta.current_page} onPaginate={@_handleOnPaginate}/>
</div>
@ProjectPaid = React.createClass
render: ->
<input className="paid-checkbox" onChange={@props.onChange} type="checkbox" name="paid" value="t">Paid</input>
@ProjectOrderBy = React.createClass
render: ->
<select onChange={@props.onChange}>
<option value="featured">Featured</option>
<option value="deadline">Deadline</option>
<option value="listed_at">Newest</option>
<option value="updated_at">Recently Active</option>
</select>
@ProjectCell = React.createClass
render: ->
p = @props.data
saveForLaterId = "save-project#{p.id}"
cx = React.addons.classSet
infoDivClasses = cx
'row mt col-centered project-info-div': true
'featured': p.featured == true
if p.paid == true
paidProject =
<div className='date-time'>
Paid Project:
<div className='fa fa-money'>$$$ </div>
</div>
else
paidProject =
<span />
favoriteText = if _.include(@props.favs, p.id) then "Unsave" else "Save for later"
<div>
<div className={infoDivClasses} data-project-id={p.id} itemscope='itemscope' itemtype='http://schema.org/Event'>
<div className='col-md-9'>
</div>
<div className='col-md-3 save-for-later-container'>
<span className='save-for-later-wrapper'>
<div className='fa fa-heart'>
<a id={saveForLaterId} className="project-favoriter" data-p={p.id} href="#">{favoriteText}
</a>
</div>
</span>
</div>
<div className='row'></div>
<div className='col-md-2'>
<div className='project-image'>
<img width="100" height="100" src={p.image_url} alt={p.name} />
</div>
</div>
<div className='col-md-7'>
<div className='title'>
<span itemprop='url'><a href={p.project_path}>{p.name}</a></span>
</div>
</div>
<div className='col-md-4'>
<div className='status'>
<div className='fa fa-calendar'>&nbsp;Deadline: {p.deadline}</div>
</div>
<div className='date-time'>
Created by:
<b><a href={p.user_path}>{p.username}</a></b>
</div>
{paidProject}
</div>
<div className='col-md-4'>
<div className='date-time'>
Category:
<b itemprop='description'>{p.category}</b>
</div>
<div className='date-time'>
Classified as:
<b itemprop='location' itemscope='itemscope' itemtype='http://schema.org/Place'>{p.classification}</b>
</div>
<div className='date-time'>
Franchise:
<b>{p.franchise_name}</b>
</div>
</div>
<div className='col-md-4'>
<div className='date-time'>
Roles Available:
<b className='past'>{p.roles_available} / {p.roles_count}</b>
</div>
<div className='date-time'>
By Gender:
<div className='fa fa-male'>
<b className='cell'>{p.male_roles_casted_count} / {p.male_roles_count}</b>
</div>
<div className='fa fa-female'>
<b className='cell'>{p.female_roles_casted_count} / {p.female_roles_count}</b>
</div>
</div>
<div className='date-time'>
Auditions Made:
<b>{p.auditions_count}</b>
</div>
</div>
</div>
</div>
@ProjectSearch = React.createClass
getInitialState: ->
searchLength: 0
componentDidMount: ->
@_subscribeToEvents()
componentWillUnmount: ->
@_unsubscribeFromEvents()
_subscribeToEvents: ->
$(@refs.search.getDOMNode()).on 'keyup', @_handleSearchOnKeyup
PubSub.subscribe 'resetButton:onClick', ()=>
@refs.search.getDOMNode().value = ''
@setState
searchLength: 0
_unsubscribeFromEvents: ->
PubSub.unsubscribe 'resetButton:onClick'
_handleOnSubmit: (e) ->
e.preventDefault()
form = this.refs.searchForm.getDOMNode()
$form = $(form)
data = $form.serialize()
@props.onFormSubmit(data)
_handleSearchOnKeyup: (e) ->
@setState
searchLength: $(e.target).val().length
_projectText: (count) ->
if count > 1 then 'casting calls' else 'casting call'
render: ->
count = @props.totalCount
projectText = @_projectText(count)
# not used
#paidEq = <input name="paid_eq" ref="paid" placeholder="Only Paid Work" type="checkbox"/>
overviewTitle = if @props.totalCount > 0 then "#{count} #{projectText} found!"
<div className="filter-wrapper">
<div className="overview-wrapper">{overviewTitle} </div>
<div className="form-wrapper">
<form ref="searchForm" onSubmit={@_handleOnSubmit}>
<input name="name_or_roles_name_cont" ref="search" placeholder="Search projects..." type="search"/>
<input className="btn btn-clear blue" type="submit" value="Search" />
{
if @state.searchLength != 0
<ResetButton text="Reset filter" styleClass="reset"/>
}
</form>
</div>
</div>
@ResetButton = React.createClass
_handleOnClick: (e) ->
e.preventDefault()
PubSub.publish 'resetButton:onClick'
render: ->
<a className={@props.styleClass} href="#" onClick={@_handleOnClick}>{@props.text}</a>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment