Rev 7051 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
import React, { useEffect, useRef, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { Card, Col, Container, Row } from 'react-bootstrap'
import { axios, debounce, jsonToParams } from '../../utils'
import { addNotification } from '../../redux/notification/notification.actions'
import styled from 'styled-components'
import SearchInput from '../../components/UI/SearchInput'
import EmptySection from '../../components/UI/EmptySection'
import WidgetLayout from '../../components/widgets/WidgetLayout'
import PaginationComponent from '../../components/UI/PaginationComponent'
import {
CardActions,
CardContent,
CardMedia,
IconButton,
Typography,
} from '@mui/material'
import { Delete, Edit } from '@mui/icons-material'
import KnowledgeEditModal from '../../components/knowledge/KnowledgeEditModal'
import ConfirmModal from '../../components/modals/ConfirmModal'
const KnowledgeCategories = styled(WidgetLayout)`
padding: 1rem;
ul {
display: flex;
flex-direction: column;
gap: 1rem;
li,
label {
cursor: pointer;
}
.selected label {
font-weight: 600;
}
}
`
const KnowledgeGrid = styled.div`
display: grid;
grid-template-columns: repeat(auto-fit, 250px);
gap: 1rem;
`
const KnowledgeCard = styled(Card)`
background-color: var(--bg-color);
border-radius: var(--border-radius);
overflow: hidden;
height: fit-content;
`
const KnowledgeSearch = styled(SearchInput)`
background-color: var(--bg-color);
`
const KnowledgeAreaPage = () => {
const [knowledges, setKnowledges] = useState([])
const [knowledgesCategories, setKnowledgesCategories] = useState([])
const [search, setSearch] = useState('')
const [category, setCategory] = useState('')
const [currentPage, setCurrentPage] = useState(1)
const [totalPages, setTotalPages] = useState(1)
const [allowAdd, setAllowAdd] = useState(false)
const [modalShow, setModalShow] = useState(null)
const addUrl = useRef('')
const actionUrl = useRef('')
const labels = useSelector(({ intl }) => intl.labels)
const dispatch = useDispatch()
const getKnowledgesInfo = (search = '', page = 1, category_id = '') => {
const urlParams = { search, page, category_id }
axios
.get(`/knowledge-area?${jsonToParams(urlParams)}`, {
headers: {
'Content-Type': 'application/json',
},
})
.then((response) => {
const { data, success } = response.data
if (!success) {
const errorMessage =
typeof data === 'string'
? data
: 'Ha ocurrido un error, por favor intente más tarde.'
dispatch(addNotification({ style: 'danger', msg: errorMessage }))
return
}
const categories = Object.entries(data.categories).map(
(values) => values[1]
)
setKnowledges(data.items)
setKnowledgesCategories(categories)
setCurrentPage(data.page)
setTotalPages(data.total_pages)
setAllowAdd(Boolean(data.link_add))
addUrl.current = data.link_add
})
.catch((error) => {
dispatch(
addNotification({
style: 'danger',
msg: 'Ha ocurrido un error, por favor intente más tarde.',
})
)
throw new Error(error)
})
}
const confirmDelete = () => {
axios
.post(actionUrl.current)
.then((response) => {
const { data, success } = response.data
if (!success) {
const errorMessage =
typeof data === 'string'
? data
: 'Ha ocurrido un error, por favor intente más tarde.'
dispatch(addNotification({ style: 'danger', msg: errorMessage }))
return
}
dispatch(addNotification({ style: 'success', msg: data }))
getKnowledgesInfo()
closeModal()
})
.catch((error) => {
dispatch(
addNotification({
style: 'danger',
msg: 'Ha ocurrido un error, por favor intente más tarde.',
})
)
throw new Error(error)
})
}
const addKnowledge = (url) => {
actionUrl.current = url
setModalShow('add')
}
const editKnowledge = (url) => {
actionUrl.current = url
setModalShow('edit')
}
const deleteKnowledge = (url) => {
actionUrl.current = url
setModalShow('delete')
}
const closeModal = () => {
actionUrl.current = ''
setModalShow(null)
}
const handleInputChange = debounce((e) => setSearch(e.target.value), 500)
useEffect(() => {
getKnowledgesInfo(search, currentPage, category)
}, [search, currentPage, category])
return (
<>
<Container as="section" className="companies-info">
<div className="company-title">
<h1 className="title mx-auto">{labels.knowledge_area_title}</h1>
{allowAdd && (
<h2
className="title cursor-pointer"
onClick={() => addKnowledge(addUrl.current)}
>
{labels.knowledge_area_add}
</h2>
)}
</div>
<Row className="gap-3">
<Col md="3">
<KnowledgeCategories>
<ul>
<li className={!category && 'selected'}>
<input
type="radio"
id="category-all"
value=""
name="category"
onChange={(e) => setCategory(e.target.value)}
hidden
/>
<label htmlFor="category-all">
{labels.knowledge_area_category_all}
</label>
</li>
{knowledgesCategories.map(({ uuid, name }) => (
<li className={category === uuid && 'selected'} key={uuid}>
<input
type="radio"
id={`category-${name}`}
name="category"
value={uuid}
onChange={(e) => setCategory(e.target.value)}
hidden
/>
<label htmlFor={`category-${name}`}>{name}</label>
</li>
))}
</ul>
</KnowledgeCategories>
</Col>
<Col className="px-0">
<KnowledgeSearch
onChange={handleInputChange}
placeholder={labels.search}
/>
<KnowledgeGrid className="mt-3">
{knowledges.length ? (
knowledges.map((knowledge, index) => (
<Item
key={index}
{...knowledge}
onEdit={editKnowledge}
onDelete={deleteKnowledge}
/>
))
) : (
<EmptySection
message={labels.error_no_record_matched_your_query}
/>
)}
</KnowledgeGrid>
<PaginationComponent
onChangePage={(newPage) => setCurrentPage(newPage)}
currentActivePage={currentPage}
pages={totalPages}
isRow
/>
</Col>
</Row>
</Container>
<KnowledgeEditModal
show={modalShow === 'edit'}
url={actionUrl.current}
categories={knowledgesCategories}
onComplete={getKnowledgesInfo}
onClose={closeModal}
isEdit
/>
<KnowledgeEditModal
show={modalShow === 'add'}
url={actionUrl.current}
categories={knowledgesCategories}
onComplete={getKnowledgesInfo}
onClose={closeModal}
/>
<ConfirmModal
show={modalShow === 'delete'}
onClose={closeModal}
onAccept={confirmDelete}
/>
</>
)
}
const Item = ({
link_delete,
link_view,
link_edit,
category,
description,
image,
title,
onEdit,
onDelete,
}) => {
return (
<>
<KnowledgeCard>
<CardMedia
component="img"
height="194"
image={image}
alt={`${title} image`}
/>
<CardContent>
<Typography variant="h5">{title}</Typography>
<Typography variant="subtitle1" color="text.secondary">
{category}
</Typography>
<Typography variant="body2" color="text.secondary">
{description}
</Typography>
</CardContent>
<CardActions disableSpacing>
{link_edit && (
<IconButton aria-label="edit" onClick={() => onEdit(link_edit)}>
<Edit />
</IconButton>
)}
{link_delete && (
<IconButton
aria-label="delete"
onClick={() => onDelete(link_delete)}
>
<Delete />
</IconButton>
)}
</CardActions>
</KnowledgeCard>
</>
)
}
export default KnowledgeAreaPage