Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 7165 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
7156 stevensc 1
import React, { useEffect, useRef, useState } from 'react'
2
import { useDispatch, useSelector } from 'react-redux'
3
import { Col, Container, Row } from 'react-bootstrap'
4
import { axios, debounce, jsonToParams } from '../../utils'
5
import { addNotification } from '../../redux/notification/notification.actions'
6
import styled from 'styled-components'
7
 
8
import SearchInput from '../../components/UI/SearchInput'
9
import EmptySection from '../../components/UI/EmptySection'
10
import WidgetLayout from '../../components/widgets/WidgetLayout'
11
import PaginationComponent from '../../components/UI/PaginationComponent'
12
 
13
import ConfirmModal from '../../components/modals/ConfirmModal'
7160 stevensc 14
import QuestionCard from '../../components/my-coach/QuestionCard'
7186 stevensc 15
import QuestionModal from '../../components/my-coach/QuestionModal'
7156 stevensc 16
 
17
const CoachCategories = styled(WidgetLayout)`
18
  padding: 1rem;
19
  ul {
20
    display: flex;
21
    flex-direction: column;
22
    gap: 1rem;
23
    li,
24
    label {
25
      cursor: pointer;
26
    }
27
    .selected label {
28
      font-weight: 600;
29
    }
30
  }
31
`
32
 
7157 stevensc 33
const QuestionsGrid = styled.div`
7156 stevensc 34
  display: grid;
7165 stevensc 35
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
7156 stevensc 36
  gap: 1rem;
37
`
38
 
39
const KnowledgeSearch = styled(SearchInput)`
40
  background-color: var(--bg-color);
41
`
42
 
43
const MyCoachPage = () => {
7157 stevensc 44
  const [questions, setQuestions] = useState([])
45
  const [questionsCategories, setQuestionsCategories] = useState([])
7156 stevensc 46
  const [search, setSearch] = useState('')
47
  const [category, setCategory] = useState('')
48
  const [currentPage, setCurrentPage] = useState(1)
49
  const [totalPages, setTotalPages] = useState(1)
50
  const [modalShow, setModalShow] = useState(null)
7158 stevensc 51
  const addUrl = useRef('/my-coach/questions/add')
7156 stevensc 52
  const actionUrl = useRef('')
53
  const labels = useSelector(({ intl }) => intl.labels)
54
  const dispatch = useDispatch()
55
 
7157 stevensc 56
  const getCategories = () => {
57
    axios
58
      .get('/my-coach', {
59
        headers: {
60
          'Content-Type': 'application/json',
61
        },
62
      })
63
      .then((response) => {
64
        const { data, success } = response.data
65
 
66
        if (!success) {
67
          const errorMessage =
68
            typeof data === 'string' ? data : labels.error_there_was_an_error
69
 
70
          dispatch(addNotification({ style: 'danger', msg: errorMessage }))
71
          return
72
        }
73
 
7158 stevensc 74
        const categories = Object.entries(data.categories).map((values) => ({
75
          name: values[1],
76
          uuid: values[0],
77
        }))
78
 
79
        setQuestionsCategories(categories)
7157 stevensc 80
      })
81
      .catch((error) => {
82
        dispatch(
83
          addNotification({
84
            style: 'danger',
85
            msg: labels.error_there_was_an_error,
86
          })
87
        )
88
        throw new Error(error)
89
      })
90
  }
91
 
92
  const getQuestions = (search = '', page = 1, category_id = '') => {
7156 stevensc 93
    const urlParams = { search, page, category_id }
94
    axios
7158 stevensc 95
      .get(`/my-coach/questions?${jsonToParams(urlParams)}`, {
7156 stevensc 96
        headers: {
97
          'Content-Type': 'application/json',
98
        },
99
      })
100
      .then((response) => {
101
        const { data, success } = response.data
102
 
103
        if (!success) {
104
          const errorMessage =
105
            typeof data === 'string' ? data : labels.error_there_was_an_error
106
 
107
          dispatch(addNotification({ style: 'danger', msg: errorMessage }))
108
          return
109
        }
110
 
7158 stevensc 111
        setQuestions(data.items)
112
        setCurrentPage(data.page)
113
        setTotalPages(data.total_pages)
7156 stevensc 114
      })
115
      .catch((error) => {
116
        dispatch(
117
          addNotification({
118
            style: 'danger',
119
            msg: labels.error_there_was_an_error,
120
          })
121
        )
122
        throw new Error(error)
123
      })
124
  }
125
 
126
  const confirmDelete = () => {
127
    axios
128
      .post(actionUrl.current)
129
      .then((response) => {
130
        const { data, success } = response.data
131
 
132
        if (!success) {
133
          const errorMessage =
134
            typeof data === 'string'
135
              ? data
136
              : 'Ha ocurrido un error, por favor intente más tarde.'
137
 
138
          dispatch(addNotification({ style: 'danger', msg: errorMessage }))
139
          return
140
        }
141
 
142
        dispatch(addNotification({ style: 'success', msg: data }))
7157 stevensc 143
        getQuestions(search, currentPage, category)
7156 stevensc 144
        closeModal()
145
      })
146
      .catch((error) => {
147
        dispatch(
148
          addNotification({
149
            style: 'danger',
150
            msg: 'Ha ocurrido un error, por favor intente más tarde.',
151
          })
152
        )
153
        throw new Error(error)
154
      })
155
  }
156
 
7157 stevensc 157
  const addQuestion = (url) => {
7156 stevensc 158
    actionUrl.current = url
159
    setModalShow('add')
160
  }
161
 
7157 stevensc 162
  const editQuestion = (url) => {
7156 stevensc 163
    actionUrl.current = url
164
    setModalShow('edit')
165
  }
166
 
7157 stevensc 167
  const deleteQuestion = (url) => {
7156 stevensc 168
    actionUrl.current = url
169
    setModalShow('delete')
170
  }
171
 
172
  const closeModal = () => {
173
    actionUrl.current = ''
174
    setModalShow(null)
175
  }
176
 
177
  const handleInputChange = debounce((e) => setSearch(e.target.value), 500)
178
 
179
  useEffect(() => {
7157 stevensc 180
    getCategories()
181
  }, [])
182
 
183
  useEffect(() => {
184
    getQuestions(search, currentPage, category)
7156 stevensc 185
  }, [search, currentPage, category])
186
 
187
  return (
188
    <>
189
      <Container as="section" className="companies-info">
190
        <div className="company-title">
7186 stevensc 191
          <h1 className="title mx-auto">{labels.my_coach}</h1>
7158 stevensc 192
          <h2
193
            className="title cursor-pointer"
194
            onClick={() => addQuestion(addUrl.current)}
195
          >
7186 stevensc 196
            {labels.my_coach_question_add}
7158 stevensc 197
          </h2>
7156 stevensc 198
        </div>
199
 
200
        <Row className="gap-3">
201
          <Col md="3">
202
            <CoachCategories>
203
              <ul>
204
                <li className={!category && 'selected'}>
205
                  <input
206
                    type="radio"
207
                    id="category-all"
208
                    value=""
209
                    name="category"
210
                    onChange={(e) => setCategory(e.target.value)}
211
                    hidden
212
                  />
213
                  <label htmlFor="category-all">
214
                    {labels.knowledge_area_category_all}
215
                  </label>
216
                </li>
7157 stevensc 217
                {questionsCategories.map(({ uuid, name }) => (
7156 stevensc 218
                  <li className={category === uuid && 'selected'} key={uuid}>
219
                    <input
220
                      type="radio"
221
                      id={`category-${name}`}
222
                      name="category"
223
                      value={uuid}
224
                      onChange={(e) => setCategory(e.target.value)}
225
                      hidden
226
                    />
227
                    <label htmlFor={`category-${name}`}>{name}</label>
228
                  </li>
229
                ))}
230
              </ul>
231
            </CoachCategories>
232
          </Col>
233
 
7165 stevensc 234
          <Col className="px-md-0">
7156 stevensc 235
            <KnowledgeSearch
236
              onChange={handleInputChange}
237
              placeholder={labels.search}
238
            />
7157 stevensc 239
            <QuestionsGrid className="mt-3">
240
              {questions.length ? (
7160 stevensc 241
                questions.map((question) => (
242
                  <QuestionCard
243
                    key={question.uuid}
7157 stevensc 244
                    onEdit={editQuestion}
245
                    onDelete={deleteQuestion}
7164 stevensc 246
                    {...question}
7156 stevensc 247
                  />
248
                ))
249
              ) : (
250
                <EmptySection
251
                  message={labels.error_no_record_matched_your_query}
252
                />
253
              )}
7157 stevensc 254
            </QuestionsGrid>
7156 stevensc 255
            <PaginationComponent
256
              onChangePage={(newPage) => setCurrentPage(newPage)}
257
              currentActivePage={currentPage}
258
              pages={totalPages}
259
              isRow
260
            />
261
          </Col>
262
        </Row>
263
      </Container>
7186 stevensc 264
      <QuestionModal
265
        show={['add', 'edit'].includes(modalShow)}
266
        onClose={closeModal}
267
        onComplete={getQuestions}
268
        url={actionUrl.current}
269
        isEdit={modalShow === 'edit'}
270
      />
7156 stevensc 271
      <ConfirmModal
272
        show={modalShow === 'delete'}
273
        onClose={closeModal}
274
        onAccept={confirmDelete}
275
      />
276
    </>
277
  )
278
}
279
 
280
export default MyCoachPage