Rev 7028 | Rev 7030 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
import React, { useEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { 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'
const KnowledgeCategories = styled(WidgetLayout)`
padding: 1rem;
ul {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
`
const KnowledgeGrid = styled.div`
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
`
const KnowledgeCard = styled(WidgetLayout)`
display: flex;
flex-direction: column;
gap: 0.5rem;
height: 100%;
padding-bottom: 1rem;
& > {
* {
margin: 0 1rem;
}
a {
width: fit-content;
img {
width: 100%;
height: auto;
}
h2 {
color: $title-color;
font-weight: 800;
}
}
h3 {
color: $subtitle-color;
font-weight: 400;
}
p {
color: $font-color;
font-weight: 400;
text-align: justify;
text-justify: inter-word;
}
}
.knowledge-record-card-actions {
display: flex;
align-items: center;
gap: 0.5rem;
& > * {
flex: 1;
max-width: calc(100% / 3);
}
}
.reaction-btn {
align-items: center;
border-radius: 10px;
display: inline-flex;
gap: 0.5rem;
justify-content: center;
padding: 10px;
position: relative;
width: -webkit-fill-available;
transition: background-color 200ms ease;
&:hover {
background-color: #f5f5f5;
}
}
.reactions {
position: absolute;
bottom: calc(100% + 0.5rem);
background-color: $bg-color;
box-shadow: 0px 0px 3px #000;
gap: 0.5rem;
left: 50%;
display: none;
padding: 0.2rem;
width: fit-content;
border-radius: 20px;
transform: translateX(-50%);
&.active {
display: flex;
}
}
`
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 labels = useSelector(({ intl }) => intl.labels)
const dispatch = useDispatch()
const getKnowledgesInfo = (search, page, category) => {
const urlParams = { search, page, category }
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
}
setKnowledges(data.items)
setKnowledgesCategories(data.categories)
setCurrentPage(data.page)
setTotalPages(data.total_pages)
setAllowAdd(Boolean(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 handleInputChange = debounce((e) => setSearch(e.target.value), 500)
useEffect(() => {
getKnowledgesInfo(search, currentPage, category)
}, [search, currentPage])
return (
<Container as="section" className="companies-info px-0">
<div className="company-title">
<h1 className="title mx-auto">{labels.knowledge_area_title}</h1>
{allowAdd && (
<h2 className="title cursor-pointer">{labels.knowledge_area_add}</h2>
)}
</div>
<Row className="gap-3">
<Col md="3">
<KnowledgeCategories>
<ul>
<li className="knowledge-category-li knowledge-category-li-selected">
<input
type="radio"
id="category-all"
value=""
onChange={(e) => setCategory(e.target.value)}
hidden
/>
<label htmlFor="category-all">
{labels.knowledge_area_category_all}
</label>
</li>
{knowledgesCategories.map(({ uuid, name }) => (
<li className="knowledge-category-li" key={uuid}>
<input
type="radio"
id={`category-${name}`}
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} />
))
) : (
<EmptySection
message={labels.error_no_record_matched_your_query}
/>
)}
</KnowledgeGrid>
<PaginationComponent
onChangePage={(newPage) => setCurrentPage(newPage)}
currentActivePage={currentPage}
pages={totalPages}
isRow
/>
</Col>
</Row>
</Container>
)
}
const Item = ({
link_delete,
link_view,
link_edit,
category,
description,
image,
title,
}) => {
return (
<KnowledgeCard>
<a
href={link_view}
target="_blank"
className="knowledge-record-card-actions-view"
rel="noreferrer"
>
<img src={image} alt={`${title} image`} />
</a>
<div className="d-flex align-items-center justify-content-between">
{link_edit && (
<button data-link="{{>link_edit}}" className="btn-knowledge-edit">
<i className="fa fa-pencil" aria-hidden="true" />
</button>
)}
{link_delete && (
<button data-link="{{>link_delete}}" className="btn-knowledge-delete">
<i className="fa fa-trash" aria-hidden="true" />
</button>
)}
</div>
<h3>{category}</h3>
<a href={link_view} target="_blank" rel="noreferrer">
<h2>{title}</h2>
</a>
<p>{description}</p>
</KnowledgeCard>
)
}
export default KnowledgeAreaPage