Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

Rev Autor Línea Nro. Línea
7033 stevensc 1
import React, { useEffect, useRef, useState } from 'react'
7025 stevensc 2
import { useDispatch, useSelector } from 'react-redux'
7030 stevensc 3
import { Card, Col, Container, Row } from 'react-bootstrap'
7020 stevensc 4
import { axios, debounce, jsonToParams } from '../../utils'
7015 stevensc 5
import { addNotification } from '../../redux/notification/notification.actions'
7025 stevensc 6
import styled from 'styled-components'
7
 
8
import SearchInput from '../../components/UI/SearchInput'
7019 stevensc 9
import EmptySection from '../../components/UI/EmptySection'
7025 stevensc 10
import WidgetLayout from '../../components/widgets/WidgetLayout'
7020 stevensc 11
import PaginationComponent from '../../components/UI/PaginationComponent'
7030 stevensc 12
import {
13
  CardActions,
14
  CardContent,
15
  CardMedia,
16
  IconButton,
17
  Typography,
18
} from '@mui/material'
19
import { Delete, Edit } from '@mui/icons-material'
7033 stevensc 20
import KnowledgeEditModal from '../../components/knowledge/KnowledgeEditModal'
7043 stevensc 21
import ConfirmModal from '../../components/modals/ConfirmModal'
7015 stevensc 22
 
7024 stevensc 23
const KnowledgeCategories = styled(WidgetLayout)`
24
  padding: 1rem;
7027 stevensc 25
  ul {
26
    display: flex;
27
    flex-direction: column;
7040 stevensc 28
    gap: 1rem;
7039 stevensc 29
    li,
30
    label {
7033 stevensc 31
      cursor: pointer;
32
    }
7039 stevensc 33
    .selected label {
7033 stevensc 34
      font-weight: 600;
35
    }
7027 stevensc 36
  }
7024 stevensc 37
`
38
 
7026 stevensc 39
const KnowledgeGrid = styled.div`
40
  display: grid;
41
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
42
  gap: 1rem;
43
`
44
 
7030 stevensc 45
const KnowledgeCard = styled(Card)`
7031 stevensc 46
  background-color: var(--bg-color);
47
  border-radius: var(--border-radius);
48
  overflow: hidden;
7032 stevensc 49
  height: fit-content;
7027 stevensc 50
`
51
 
7024 stevensc 52
const KnowledgeSearch = styled(SearchInput)`
53
  background-color: var(--bg-color);
54
`
55
 
7020 stevensc 56
const KnowledgeAreaPage = () => {
7015 stevensc 57
  const [knowledges, setKnowledges] = useState([])
58
  const [knowledgesCategories, setKnowledgesCategories] = useState([])
7020 stevensc 59
  const [search, setSearch] = useState('')
7023 stevensc 60
  const [category, setCategory] = useState('')
7020 stevensc 61
  const [currentPage, setCurrentPage] = useState(1)
62
  const [totalPages, setTotalPages] = useState(1)
63
  const [allowAdd, setAllowAdd] = useState(false)
7033 stevensc 64
  const [modalShow, setModalShow] = useState(null)
7034 stevensc 65
  const actionUrl = useRef('')
7015 stevensc 66
  const labels = useSelector(({ intl }) => intl.labels)
67
  const dispatch = useDispatch()
68
 
7033 stevensc 69
  const getKnowledgesInfo = (search = '', page = 1, category_id = '') => {
70
    const urlParams = { search, page, category_id }
7015 stevensc 71
    axios
7021 stevensc 72
      .get(`/knowledge-area?${jsonToParams(urlParams)}`, {
7015 stevensc 73
        headers: {
74
          'Content-Type': 'application/json',
75
        },
76
      })
77
      .then((response) => {
7019 stevensc 78
        const { data, success } = response.data
79
 
80
        if (!success) {
81
          const errorMessage =
82
            typeof data === 'string'
83
              ? data
84
              : 'Ha ocurrido un error, por favor intente más tarde.'
85
 
86
          dispatch(addNotification({ style: 'danger', msg: errorMessage }))
87
          return
88
        }
89
 
90
        setKnowledges(data.items)
7020 stevensc 91
        setKnowledgesCategories(data.categories)
92
        setCurrentPage(data.page)
93
        setTotalPages(data.total_pages)
94
        setAllowAdd(Boolean(data.link_add))
7015 stevensc 95
      })
96
      .catch((error) => {
97
        dispatch(
98
          addNotification({
99
            style: 'danger',
100
            msg: 'Ha ocurrido un error, por favor intente más tarde.',
101
          })
102
        )
103
        throw new Error(error)
104
      })
7020 stevensc 105
  }
7015 stevensc 106
 
7043 stevensc 107
  const confirmDelete = () => {
108
    axios
109
      .post(actionUrl.current)
110
      .then((response) => {
111
        const { data, success } = response.data
112
 
113
        if (!success) {
114
          const errorMessage =
115
            typeof data === 'string'
116
              ? data
117
              : 'Ha ocurrido un error, por favor intente más tarde.'
118
 
119
          dispatch(addNotification({ style: 'danger', msg: errorMessage }))
120
          return
121
        }
122
 
123
        dispatch(addNotification({ style: 'success', msg: data }))
7044 stevensc 124
        getKnowledgesInfo()
125
        closeModal()
7043 stevensc 126
      })
127
      .catch((error) => {
128
        dispatch(
129
          addNotification({
130
            style: 'danger',
131
            msg: 'Ha ocurrido un error, por favor intente más tarde.',
132
          })
133
        )
134
        throw new Error(error)
135
      })
136
  }
137
 
7033 stevensc 138
  const editKnowledge = (url) => {
139
    actionUrl.current = url
140
    setModalShow('edit')
141
  }
142
 
7043 stevensc 143
  const deleteKnowledge = (url) => {
144
    actionUrl.current = url
145
    setModalShow('delete')
146
  }
147
 
7033 stevensc 148
  const closeModal = () => {
7036 stevensc 149
    actionUrl.current = ''
7033 stevensc 150
    setModalShow(null)
151
  }
152
 
7022 stevensc 153
  const handleInputChange = debounce((e) => setSearch(e.target.value), 500)
7020 stevensc 154
 
155
  useEffect(() => {
7023 stevensc 156
    getKnowledgesInfo(search, currentPage, category)
7030 stevensc 157
  }, [search, currentPage, category])
7020 stevensc 158
 
7015 stevensc 159
  return (
7033 stevensc 160
    <>
161
      <Container as="section" className="companies-info px-0">
162
        <div className="company-title">
163
          <h1 className="title mx-auto">{labels.knowledge_area_title}</h1>
164
          {allowAdd && (
165
            <h2 className="title cursor-pointer">
166
              {labels.knowledge_area_add}
167
            </h2>
168
          )}
169
        </div>
7015 stevensc 170
 
7033 stevensc 171
        <Row className="gap-3">
172
          <Col md="3">
173
            <KnowledgeCategories>
174
              <ul>
7039 stevensc 175
                <li className={!category && 'selected'}>
7026 stevensc 176
                  <input
177
                    type="radio"
7033 stevensc 178
                    id="category-all"
179
                    value=""
7043 stevensc 180
                    name="category"
7026 stevensc 181
                    onChange={(e) => setCategory(e.target.value)}
182
                    hidden
183
                  />
7039 stevensc 184
                  <label htmlFor="category-all">
7033 stevensc 185
                    {labels.knowledge_area_category_all}
186
                  </label>
7026 stevensc 187
                </li>
7033 stevensc 188
                {knowledgesCategories.map(({ uuid, name }) => (
7039 stevensc 189
                  <li className={category === uuid && 'selected'} key={uuid}>
7033 stevensc 190
                    <input
191
                      type="radio"
192
                      id={`category-${name}`}
7042 stevensc 193
                      name="category"
7033 stevensc 194
                      value={uuid}
195
                      onChange={(e) => setCategory(e.target.value)}
196
                      hidden
197
                    />
7039 stevensc 198
                    <label htmlFor={`category-${name}`}>{name}</label>
7033 stevensc 199
                  </li>
200
                ))}
201
              </ul>
202
            </KnowledgeCategories>
203
          </Col>
7015 stevensc 204
 
7033 stevensc 205
          <Col className="px-0">
206
            <KnowledgeSearch
207
              onChange={handleInputChange}
208
              placeholder={labels.search}
209
            />
7015 stevensc 210
 
7033 stevensc 211
            <KnowledgeGrid className="mt-3">
212
              {knowledges.length ? (
213
                knowledges.map((knowledge, index) => (
7043 stevensc 214
                  <Item
215
                    key={index}
216
                    {...knowledge}
217
                    onEdit={editKnowledge}
218
                    onDelete={deleteKnowledge}
219
                  />
7033 stevensc 220
                ))
221
              ) : (
222
                <EmptySection
223
                  message={labels.error_no_record_matched_your_query}
224
                />
225
              )}
226
            </KnowledgeGrid>
227
            <PaginationComponent
228
              onChangePage={(newPage) => setCurrentPage(newPage)}
229
              currentActivePage={currentPage}
230
              pages={totalPages}
231
              isRow
232
            />
233
          </Col>
234
        </Row>
235
      </Container>
236
      <KnowledgeEditModal
237
        show={modalShow === 'edit'}
238
        url={actionUrl.current}
239
        categories={knowledgesCategories}
240
        onComplete={getKnowledgesInfo}
241
        onClose={closeModal}
242
      />
7043 stevensc 243
      <ConfirmModal
244
        show={modalShow === 'delete'}
245
        onClose={closeModal}
246
        onAccept={confirmDelete}
247
      />
7033 stevensc 248
    </>
7015 stevensc 249
  )
250
}
251
 
7019 stevensc 252
const Item = ({
253
  link_delete,
254
  link_view,
255
  link_edit,
256
  category,
257
  description,
258
  image,
259
  title,
7033 stevensc 260
  onEdit,
7043 stevensc 261
  onDelete,
7019 stevensc 262
}) => {
263
  return (
7030 stevensc 264
    <>
265
      <KnowledgeCard>
266
        <CardMedia
267
          component="img"
268
          height="194"
269
          image={image}
270
          alt={`${title} image`}
271
        />
272
        <CardContent>
7032 stevensc 273
          <Typography variant="h5">{title}</Typography>
7031 stevensc 274
          <Typography variant="subtitle1" color="text.secondary">
275
            {category}
276
          </Typography>
7030 stevensc 277
          <Typography variant="body2" color="text.secondary">
278
            {description}
279
          </Typography>
280
        </CardContent>
281
        <CardActions disableSpacing>
282
          {link_edit && (
7033 stevensc 283
            <IconButton aria-label="edit" onClick={() => onEdit(link_edit)}>
7030 stevensc 284
              <Edit />
285
            </IconButton>
286
          )}
287
          {link_delete && (
7043 stevensc 288
            <IconButton
289
              aria-label="delete"
290
              onClick={() => onDelete(link_delete)}
291
            >
7030 stevensc 292
              <Delete />
293
            </IconButton>
294
          )}
295
        </CardActions>
296
      </KnowledgeCard>
297
    </>
7019 stevensc 298
  )
299
}
300
 
7015 stevensc 301
export default KnowledgeAreaPage