Advertisement
dfghgfhplkjbv

src/components/AllJobs/AllJobs.js

Feb 25th, 2019
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.61 KB | None | 0 0
  1. import React, { Component } from 'react'
  2. import styles from './AllJobs.module.scss'
  3. import posed, { PoseGroup } from 'react-pose'
  4. import shuffle from 'src/shuffle'
  5. import { Link } from 'gatsby'
  6. import { getLink } from 'src/utils'
  7. import { formatMessage } from 'src/translations'
  8.  
  9. const Item = posed.div({
  10. flip: {
  11. scale: 1,
  12. transition: {
  13. scale: {
  14. type: 'spring',
  15. velocity: 3,
  16. },
  17. default: {
  18. type: 'spring',
  19. },
  20. },
  21. // transition: { type: 'spring', stiffness: 100 },
  22. },
  23. })
  24.  
  25. class AllJobs extends Component {
  26. constructor(props) {
  27. super(props)
  28. this.defaultExperienceOption = this.props.locale === 'ru' ? 'Уровень опыта' : 'Experience level'
  29. this.searchInputRef = React.createRef()
  30. }
  31.  
  32. state = {
  33. preparedJobs: this.props.jobs.filter(({ node: slug }) => slug !== '_'),
  34. selectedExperience: this.defaultExperienceOption,
  35. }
  36.  
  37. handleTagClick = (tagTitle) => {
  38. this.setState(
  39. {
  40. preparedJobs: this.props.jobs.filter(
  41. ({
  42. node: {
  43. tag: { title },
  44. },
  45. }) => title === tagTitle,
  46. ),
  47. },
  48. () =>
  49. this.setState({
  50. preparedJobs: shuffle(
  51. this.props.jobs.filter(
  52. ({
  53. node: {
  54. tag: { title },
  55. },
  56. }) => title === tagTitle,
  57. ),
  58. ),
  59. }),
  60. )
  61. }
  62.  
  63. handleExperienceChange = (event) => {
  64. const selectedExperience = event.target.value
  65. const filteredJobs = this.props.jobs.filter(({ node: { experienceLevel: { title: experience } } }) => {
  66. if (selectedExperience === experience) {
  67. return true
  68. }
  69. if (selectedExperience === this.defaultExperienceOption) {
  70. return true
  71. }
  72. })
  73. this.setState({ preparedJobs: filteredJobs, selectedExperience: selectedExperience })
  74. }
  75.  
  76. handleClearFiltersClick = () => {
  77. this.searchInputRef.current.value = ''
  78. this.setState({ preparedJobs: this.props.jobs, selectedExperience: this.defaultExperienceOption })
  79. }
  80.  
  81. handleSubmit = (event) => {
  82. event.preventDefault()
  83. this.setState({ selectedExperience: this.defaultExperienceOption })
  84. this.searchByKeyWord(this.searchInputRef.current.value)
  85. }
  86.  
  87. searchByKeyWord = (query) => {
  88. const result = this.props.jobs.filter(({ node: { title } }) => {
  89. if (title.toLocaleLowerCase().indexOf(query.toLocaleLowerCase()) >= 0) {
  90. return true
  91. }
  92. return false
  93. })
  94. this.setState({ preparedJobs: result })
  95. }
  96.  
  97. render() {
  98. const { preparedJobs } = this.state
  99. const { jobTags, experienceLevels, locale } = this.props
  100.  
  101. return (
  102. <>
  103. <div className={styles.cover} />
  104. <div className={styles.root}>
  105. <div className={styles.inner}>
  106. <div className={styles.categoriesInnerContainer}>
  107. <h1>{formatMessage(locale, 'selectJobCategories')}</h1>
  108. <div className={styles.tags}>
  109. {jobTags.map(({ node: { id, title } }) => (
  110. <button className={styles.tag} key={id} onClick={() => this.handleTagClick(title)}>
  111. {title}
  112. </button>
  113. ))}
  114. </div>
  115. <hr />
  116. <div className={styles.filters}>
  117. <form className={styles.filtersForm} onSubmit={this.handleSubmit}>
  118. <div className={styles.filtersContainer}>
  119. <select
  120. className={styles.level}
  121. value={this.state.selectedExperience}
  122. onChange={this.handleExperienceChange}
  123. >
  124. <option key="default" value={this.defaultExperienceOption}>
  125. {this.defaultExperienceOption}
  126. </option>
  127. {experienceLevels.map(({ node: { id, title } }) => (
  128. <option key={id} value={title}>
  129. {title}
  130. </option>
  131. ))}
  132. </select>
  133. <input
  134. className={styles.search}
  135. ref={this.searchInputRef}
  136. placeholder={formatMessage(locale, 'searchByKeyword')}
  137. />
  138. </div>
  139. </form>
  140. <button className={styles.clear} onClick={this.handleClearFiltersClick}>
  141. {formatMessage(locale, 'clearFilters')}
  142. </button>
  143. </div>
  144. </div>
  145. </div>
  146. <div className={styles.jobsContainer}>
  147. <div className={styles.listContainer}>
  148. <div className={styles.total}>
  149. <h3>{formatMessage(locale, 'searchResult')}</h3>
  150. <span>{preparedJobs.length}</span>
  151. </div>
  152. <div className={styles.listJobs}>
  153. <PoseGroup>
  154. {preparedJobs.map(
  155. ({
  156. node: {
  157. title,
  158. description,
  159. locationDescription,
  160. companyLogo: { url: companyLogo },
  161. slug,
  162. id,
  163. },
  164. }) => (
  165. <Item key={id}>
  166. <Link to={getLink(locale, `job/${slug}`)} key={title} className={styles.jobLink}>
  167. <div className={styles.oneJob}>
  168. <div className={styles.companyLogo}>
  169. <img src={companyLogo} alt="" />
  170. </div>
  171. <div className={styles.jobInfo}>
  172. <div className={styles.title}>{title}</div>
  173. <div>
  174. <div className={styles.location}>{locationDescription}</div>
  175. <div className={styles.description}>
  176. {description.length >= 245 ? `${description.substring(0, 245)}...` : description}
  177. </div>
  178. </div>
  179. </div>
  180. </div>
  181. </Link>
  182. </Item>
  183. ),
  184. )}
  185. </PoseGroup>
  186. </div>
  187. </div>
  188. </div>
  189. </div>
  190. </>
  191. )
  192. }
  193. }
  194.  
  195. export default AllJobs
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement