Advertisement
dfghgfhplkjbv

src/components/AllJobs/AllJobs.js

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