🎨 website/utils API_URL + standardJS
This commit is contained in:
@ -6,42 +6,68 @@ import AddEditFunction from '../../components/FunctionAdmin/AddEditFunction'
|
||||
import EditArticleFunction from '../../components/FunctionAdmin/EditArticleFunction'
|
||||
import EditFormFunction from '../../components/FunctionAdmin/EditFormFunction'
|
||||
import redirect from '../../utils/redirect'
|
||||
import api from '../../utils/api'
|
||||
import { API_URL } from '../../utils/config/config'
|
||||
import api, { API_URL } from '../../utils/api'
|
||||
import '../../components/FunctionPage/FunctionTabs.css'
|
||||
import '../../public/css/pages/admin.css'
|
||||
|
||||
const AdminFunctionComponent = (props) => {
|
||||
const AdminFunctionComponent = props => {
|
||||
const [slideIndex, setSlideIndex] = useState(0)
|
||||
|
||||
const handleDeleteFunction = async () => {
|
||||
await api.delete(`/admin/functions/${props.functionInfo.id}`, { headers: { Authorization: props.user.token } })
|
||||
await api.delete(`/admin/functions/${props.functionInfo.id}`, {
|
||||
headers: { Authorization: props.user.token }
|
||||
})
|
||||
redirect({}, '/admin')
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<HeadTag title={props.functionInfo.title} description={props.functionInfo.description} image={API_URL + props.functionInfo.image} />
|
||||
<HeadTag
|
||||
title={props.functionInfo.title}
|
||||
description={props.functionInfo.description}
|
||||
image={API_URL + props.functionInfo.image}
|
||||
/>
|
||||
|
||||
<div className='container-fluid'>
|
||||
<div className='container'>
|
||||
<div className='row justify-content-center'>
|
||||
<ul className='FunctionTabs__nav'>
|
||||
<li className='FunctionTabs__nav-item'>
|
||||
<a onClick={() => setSlideIndex(0)} className={`FunctionTabs__nav-link ${(slideIndex === 0) && 'FunctionTabs__nav-link-active'}`}>✒️ Modifier</a>
|
||||
<a
|
||||
onClick={() => setSlideIndex(0)}
|
||||
className={`FunctionTabs__nav-link ${slideIndex === 0 &&
|
||||
'FunctionTabs__nav-link-active'}`}
|
||||
>
|
||||
✒️ Modifier
|
||||
</a>
|
||||
</li>
|
||||
<li className='FunctionTabs__nav-item'>
|
||||
<a onClick={() => setSlideIndex(1)} className={`FunctionTabs__nav-link ${(slideIndex === 1) && 'FunctionTabs__nav-link-active'}`}>📝 Article</a>
|
||||
<a
|
||||
onClick={() => setSlideIndex(1)}
|
||||
className={`FunctionTabs__nav-link ${slideIndex === 1 &&
|
||||
'FunctionTabs__nav-link-active'}`}
|
||||
>
|
||||
📝 Article
|
||||
</a>
|
||||
</li>
|
||||
<li className='FunctionTabs__nav-item'>
|
||||
<a onClick={() => setSlideIndex(2)} className={`FunctionTabs__nav-link ${(slideIndex === 2) && 'FunctionTabs__nav-link-active'}`}>⚙️ Utilisation</a>
|
||||
<a
|
||||
onClick={() => setSlideIndex(2)}
|
||||
className={`FunctionTabs__nav-link ${slideIndex === 2 &&
|
||||
'FunctionTabs__nav-link-active'}`}
|
||||
>
|
||||
⚙️ Utilisation
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='container-fluid'>
|
||||
<SwipeableViews onChangeIndex={(index) => setSlideIndex(index)} index={slideIndex}>
|
||||
<SwipeableViews
|
||||
onChangeIndex={index => setSlideIndex(index)}
|
||||
index={slideIndex}
|
||||
>
|
||||
<div className='Admin__Function-slide'>
|
||||
<AddEditFunction
|
||||
defaultInputState={{ ...props.functionInfo }}
|
||||
@ -49,7 +75,9 @@ const AdminFunctionComponent = (props) => {
|
||||
isEditing
|
||||
/>
|
||||
<div style={{ marginBottom: '30px' }} className='text-center'>
|
||||
<button onClick={handleDeleteFunction} className='btn btn-dark'>Supprimer la fonction</button>
|
||||
<button onClick={handleDeleteFunction} className='btn btn-dark'>
|
||||
Supprimer la fonction
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className='Admin__Function-slide'>
|
||||
@ -72,8 +100,9 @@ export async function getServerSideProps (context) {
|
||||
if (!user.isAdmin) {
|
||||
return redirect(context, '/404')
|
||||
}
|
||||
return api.get(`/admin/functions/${slug}`, { headers: { Authorization: user.token } })
|
||||
.then((response) => {
|
||||
return api
|
||||
.get(`/admin/functions/${slug}`, { headers: { Authorization: user.token } })
|
||||
.then(response => {
|
||||
return {
|
||||
props: {
|
||||
user,
|
||||
|
@ -10,54 +10,77 @@ import AddEditFunction from '../../components/FunctionAdmin/AddEditFunction'
|
||||
import redirect from '../../utils/redirect'
|
||||
import '../../public/css/pages/admin.css'
|
||||
|
||||
const Admin = (props) => {
|
||||
const Admin = props => {
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
|
||||
const toggleModal = () => setIsOpen(!isOpen)
|
||||
|
||||
return (
|
||||
<>
|
||||
<HeadTag title='Admin - FunctionProject' description="Page d'administration de FunctionProject." />
|
||||
<HeadTag
|
||||
title='Admin - FunctionProject'
|
||||
description="Page d'administration de FunctionProject."
|
||||
/>
|
||||
|
||||
{/* Création d'une fonction */}
|
||||
{(isOpen)
|
||||
? (
|
||||
<Modal toggleModal={toggleModal}>
|
||||
<div className='Admin__Modal__container container-fluid'>
|
||||
<div className='Admin__Modal__row row'>
|
||||
<div className='col-24'>
|
||||
<div className='Admin__Modal-top-container row'>
|
||||
<div className='col-24'>
|
||||
<span onClick={toggleModal} style={{ cursor: 'pointer', position: 'absolute', left: 0 }}>
|
||||
<FontAwesomeIcon icon={faTimes} style={{ width: '1.5rem', color: 'red' }} />
|
||||
</span>
|
||||
<h2 className='text-center'>Crée une nouvelle fonction</h2>
|
||||
</div>
|
||||
{isOpen ? (
|
||||
<Modal toggleModal={toggleModal}>
|
||||
<div className='Admin__Modal__container container-fluid'>
|
||||
<div className='Admin__Modal__row row'>
|
||||
<div className='col-24'>
|
||||
<div className='Admin__Modal-top-container row'>
|
||||
<div className='col-24'>
|
||||
<span
|
||||
onClick={toggleModal}
|
||||
style={{
|
||||
cursor: 'pointer',
|
||||
position: 'absolute',
|
||||
left: 0
|
||||
}}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={faTimes}
|
||||
style={{ width: '1.5rem', color: 'red' }}
|
||||
/>
|
||||
</span>
|
||||
<h2 className='text-center'>Crée une nouvelle fonction</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='col-24'>
|
||||
<AddEditFunction defaultInputState={{ type: 'form' }} {...props} />
|
||||
</div>
|
||||
<div className='col-24'>
|
||||
<AddEditFunction
|
||||
defaultInputState={{ type: 'form' }}
|
||||
{...props}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
)
|
||||
|
||||
: (
|
||||
<FunctionsList isAdmin token={props.user.token}>
|
||||
<div className='col-24'>
|
||||
<h1 className='Functions__title'>Administration</h1>
|
||||
<button onClick={toggleModal} style={{ margin: '0 0 40px 0' }} className='btn btn-dark'>Crée une nouvelle fonction</button>
|
||||
<Link href='/admin/manageCategories'>
|
||||
<button style={{ margin: '0 0 0 20px' }} className='btn btn-dark'>Gérer les catégories</button>
|
||||
</Link>
|
||||
<Link href='/admin/manageQuotes'>
|
||||
<button style={{ margin: '0 0 0 20px' }} className='btn btn-dark'>Gérer les citations</button>
|
||||
</Link>
|
||||
</div>
|
||||
</FunctionsList>
|
||||
)}
|
||||
</div>
|
||||
</Modal>
|
||||
) : (
|
||||
<FunctionsList isAdmin token={props.user.token}>
|
||||
<div className='col-24'>
|
||||
<h1 className='Functions__title'>Administration</h1>
|
||||
<button
|
||||
onClick={toggleModal}
|
||||
style={{ margin: '0 0 40px 0' }}
|
||||
className='btn btn-dark'
|
||||
>
|
||||
Crée une nouvelle fonction
|
||||
</button>
|
||||
<Link href='/admin/manageCategories'>
|
||||
<button style={{ margin: '0 0 0 20px' }} className='btn btn-dark'>
|
||||
Gérer les catégories
|
||||
</button>
|
||||
</Link>
|
||||
<Link href='/admin/manageQuotes'>
|
||||
<button style={{ margin: '0 0 0 20px' }} className='btn btn-dark'>
|
||||
Gérer les citations
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
</FunctionsList>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -15,23 +15,36 @@ import '../../public/css/pages/admin.css'
|
||||
|
||||
const defaultCategoryState = { name: '', color: '#ffffff' }
|
||||
|
||||
const AddEditCategory = (props) => {
|
||||
const AddEditCategory = props => {
|
||||
const [inputState, setInputState] = useState(props.defaultInputState)
|
||||
const [message, setMessage] = useState('')
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
|
||||
const handleChange = (event, isTypeCheck = false) => {
|
||||
const inputStateNew = { ...inputState }
|
||||
inputStateNew[event.target.name] = (event.target.files != null) ? event.target.files[0] : (isTypeCheck) ? event.target.checked : event.target.value
|
||||
inputStateNew[event.target.name] =
|
||||
event.target.files != null
|
||||
? event.target.files[0]
|
||||
: isTypeCheck
|
||||
? event.target.checked
|
||||
: event.target.value
|
||||
setInputState(inputStateNew)
|
||||
}
|
||||
|
||||
const apiCallCategory = () => {
|
||||
if (props.isEditing) return api.put(`/admin/categories/${inputState.id}`, { name: inputState.name, color: inputState.color }, { headers: { Authorization: props.user.token } })
|
||||
return api.post('/admin/categories', inputState, { headers: { Authorization: props.user.token } })
|
||||
if (props.isEditing) {
|
||||
return api.put(
|
||||
`/admin/categories/${inputState.id}`,
|
||||
{ name: inputState.name, color: inputState.color },
|
||||
{ headers: { Authorization: props.user.token } }
|
||||
)
|
||||
}
|
||||
return api.post('/admin/categories', inputState, {
|
||||
headers: { Authorization: props.user.token }
|
||||
})
|
||||
}
|
||||
|
||||
const handleSubmit = (event) => {
|
||||
const handleSubmit = event => {
|
||||
event.preventDefault()
|
||||
setIsLoading(true)
|
||||
apiCallCategory()
|
||||
@ -39,8 +52,10 @@ const AddEditCategory = (props) => {
|
||||
setIsLoading(false)
|
||||
window.location.reload(true)
|
||||
})
|
||||
.catch((error) => {
|
||||
setMessage(`<p class="form-error"><b>Erreur:</b> ${error.response.data.message}</p>`)
|
||||
.catch(error => {
|
||||
setMessage(
|
||||
`<p class="form-error"><b>Erreur:</b> ${error.response.data.message}</p>`
|
||||
)
|
||||
setIsLoading(false)
|
||||
})
|
||||
}
|
||||
@ -51,10 +66,20 @@ const AddEditCategory = (props) => {
|
||||
<div className='col-24'>
|
||||
<div className='Admin__Modal-top-container row'>
|
||||
<div className='col-24'>
|
||||
<span onClick={props.handleToggleModal} style={{ cursor: 'pointer', position: 'absolute', left: 0 }}>
|
||||
<FontAwesomeIcon icon={faTimes} style={{ width: '1.5rem', color: 'red' }} />
|
||||
<span
|
||||
onClick={props.handleToggleModal}
|
||||
style={{ cursor: 'pointer', position: 'absolute', left: 0 }}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={faTimes}
|
||||
style={{ width: '1.5rem', color: 'red' }}
|
||||
/>
|
||||
</span>
|
||||
<h2 className='text-center'>{(props.isEditing) ? 'Modifier la catégorie' : 'Crée une nouvelle catégorie'}</h2>
|
||||
<h2 className='text-center'>
|
||||
{props.isEditing
|
||||
? 'Modifier la catégorie'
|
||||
: 'Crée une nouvelle catégorie'}
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -62,25 +87,39 @@ const AddEditCategory = (props) => {
|
||||
<div className='col-24'>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className='form-group'>
|
||||
<label className='form-label' htmlFor='name'>Nom :</label>
|
||||
<input value={inputState.name} onChange={handleChange} type='text' name='name' id='name' className='form-control' placeholder='(e.g : ✨ Utilitaires)' />
|
||||
<label className='form-label' htmlFor='name'>
|
||||
Nom :
|
||||
</label>
|
||||
<input
|
||||
value={inputState.name}
|
||||
onChange={handleChange}
|
||||
type='text'
|
||||
name='name'
|
||||
id='name'
|
||||
className='form-control'
|
||||
placeholder='(e.g : ✨ Utilitaires)'
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='form-group'>
|
||||
<label className='form-label' htmlFor='title'>Couleur :</label>
|
||||
<PhotoshopPicker color={inputState.color} onChange={(color) => handleChange({ target: { name: 'color', value: color.hex } })} />
|
||||
<label className='form-label' htmlFor='title'>
|
||||
Couleur :
|
||||
</label>
|
||||
<PhotoshopPicker
|
||||
color={inputState.color}
|
||||
onChange={color =>
|
||||
handleChange({ target: { name: 'color', value: color.hex } })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='form-group text-center'>
|
||||
<button type='submit' className='btn btn-dark'>Envoyer</button>
|
||||
<button type='submit' className='btn btn-dark'>
|
||||
Envoyer
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div className='form-result text-center'>
|
||||
{
|
||||
(isLoading)
|
||||
? <Loader />
|
||||
: htmlParser(message)
|
||||
}
|
||||
{isLoading ? <Loader /> : htmlParser(message)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -88,22 +127,26 @@ const AddEditCategory = (props) => {
|
||||
)
|
||||
}
|
||||
|
||||
const manageCategories = (props) => {
|
||||
const manageCategories = props => {
|
||||
const [, categories] = useAPI('/categories')
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
const [isEditing, setIsEditing] = useState(false)
|
||||
const [defaultInputState, setDefaultInputState] = useState(defaultCategoryState)
|
||||
const [defaultInputState, setDefaultInputState] = useState(
|
||||
defaultCategoryState
|
||||
)
|
||||
|
||||
const toggleModal = () => setIsOpen(!isOpen)
|
||||
|
||||
const handleRemoveCategory = async (categoryId) => {
|
||||
const handleRemoveCategory = async categoryId => {
|
||||
try {
|
||||
await api.delete(`/admin/categories/${categoryId}`, { headers: { Authorization: props.user.token } })
|
||||
await api.delete(`/admin/categories/${categoryId}`, {
|
||||
headers: { Authorization: props.user.token }
|
||||
})
|
||||
window.location.reload(true)
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const handleEditCategory = (categoryInfo) => {
|
||||
const handleEditCategory = categoryInfo => {
|
||||
setDefaultInputState(categoryInfo)
|
||||
setIsEditing(true)
|
||||
toggleModal()
|
||||
@ -111,64 +154,124 @@ const manageCategories = (props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<HeadTag title='Admin - FunctionProject' description="Page d'administration de FunctionProject. Gérer les catégories." />
|
||||
<HeadTag
|
||||
title='Admin - FunctionProject'
|
||||
description="Page d'administration de FunctionProject. Gérer les catégories."
|
||||
/>
|
||||
|
||||
{
|
||||
(isOpen)
|
||||
? (
|
||||
<Modal>
|
||||
<AddEditCategory handleToggleModal={toggleModal} defaultInputState={defaultInputState} {...props} isEditing={isEditing} />
|
||||
</Modal>
|
||||
)
|
||||
: (
|
||||
<div className='container-fluid text-center'>
|
||||
<div className='row justify-content-center'>
|
||||
<div className='col-24'>
|
||||
<h1>Gérer les catégories</h1>
|
||||
<button onClick={() => { setDefaultInputState(defaultCategoryState); toggleModal(); setIsEditing(false) }} style={{ margin: '0 0 40px 0' }} className='btn btn-dark'>Ajouter une catégorie</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className='row justify-content-center'>
|
||||
<div className='container-fluid'>
|
||||
<div className='col-24 table-column'>
|
||||
<table className='table'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th className='table-row' scope='col'>id</th>
|
||||
<th className='table-row' scope='col'>name</th>
|
||||
<th className='table-row' scope='col'>color</th>
|
||||
<th className='table-row' scope='col'>createdAt</th>
|
||||
<th className='table-row' scope='col'>updatedAt</th>
|
||||
<th className='table-row' scope='col'>Modifier</th>
|
||||
<th className='table-row' scope='col'>Supprimer</th>
|
||||
{isOpen ? (
|
||||
<Modal>
|
||||
<AddEditCategory
|
||||
handleToggleModal={toggleModal}
|
||||
defaultInputState={defaultInputState}
|
||||
{...props}
|
||||
isEditing={isEditing}
|
||||
/>
|
||||
</Modal>
|
||||
) : (
|
||||
<div className='container-fluid text-center'>
|
||||
<div className='row justify-content-center'>
|
||||
<div className='col-24'>
|
||||
<h1>Gérer les catégories</h1>
|
||||
<button
|
||||
onClick={() => {
|
||||
setDefaultInputState(defaultCategoryState)
|
||||
toggleModal()
|
||||
setIsEditing(false)
|
||||
}}
|
||||
style={{ margin: '0 0 40px 0' }}
|
||||
className='btn btn-dark'
|
||||
>
|
||||
Ajouter une catégorie
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className='row justify-content-center'>
|
||||
<div className='container-fluid'>
|
||||
<div className='col-24 table-column'>
|
||||
<table className='table'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th className='table-row' scope='col'>
|
||||
id
|
||||
</th>
|
||||
<th className='table-row' scope='col'>
|
||||
name
|
||||
</th>
|
||||
<th className='table-row' scope='col'>
|
||||
color
|
||||
</th>
|
||||
<th className='table-row' scope='col'>
|
||||
createdAt
|
||||
</th>
|
||||
<th className='table-row' scope='col'>
|
||||
updatedAt
|
||||
</th>
|
||||
<th className='table-row' scope='col'>
|
||||
Modifier
|
||||
</th>
|
||||
<th className='table-row' scope='col'>
|
||||
Supprimer
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{categories.map(category => {
|
||||
return (
|
||||
<tr
|
||||
key={category.id}
|
||||
style={{ backgroundColor: category.color }}
|
||||
>
|
||||
<td className='table-row'>{category.id}</td>
|
||||
<td className='table-row'>{category.name}</td>
|
||||
<td className='table-row'>{category.color}</td>
|
||||
<td className='table-row'>
|
||||
{date.format(
|
||||
new Date(category.createdAt),
|
||||
'DD/MM/YYYY à HH:mm',
|
||||
true
|
||||
)}
|
||||
</td>
|
||||
<td className='table-row'>
|
||||
{date.format(
|
||||
new Date(category.updatedAt),
|
||||
'DD/MM/YYYY à HH:mm',
|
||||
true
|
||||
)}
|
||||
</td>
|
||||
<td
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() =>
|
||||
handleEditCategory({
|
||||
name: category.name,
|
||||
color: category.color,
|
||||
id: category.id
|
||||
})}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={faPen}
|
||||
style={{ width: '1.5rem' }}
|
||||
/>
|
||||
</td>
|
||||
<td
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => handleRemoveCategory(category.id)}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={faTrash}
|
||||
style={{ width: '1.5rem' }}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{categories.map((category) => {
|
||||
return (
|
||||
<tr key={category.id} style={{ backgroundColor: category.color }}>
|
||||
<td className='table-row'>{category.id}</td>
|
||||
<td className='table-row'>{category.name}</td>
|
||||
<td className='table-row'>{category.color}</td>
|
||||
<td className='table-row'>{date.format(new Date(category.createdAt), 'DD/MM/YYYY à HH:mm', true)}</td>
|
||||
<td className='table-row'>{date.format(new Date(category.updatedAt), 'DD/MM/YYYY à HH:mm', true)}</td>
|
||||
<td style={{ cursor: 'pointer' }} onClick={() => handleEditCategory({ name: category.name, color: category.color, id: category.id })}>
|
||||
<FontAwesomeIcon icon={faPen} style={{ width: '1.5rem' }} />
|
||||
</td>
|
||||
<td style={{ cursor: 'pointer' }} onClick={() => handleRemoveCategory(category.id)}>
|
||||
<FontAwesomeIcon icon={faTrash} style={{ width: '1.5rem' }} />
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -8,8 +8,12 @@ import HeadTag from '../../components/HeadTag'
|
||||
import api from '../../utils/api'
|
||||
import '../../public/css/pages/admin.css'
|
||||
|
||||
const manageQuotes = (props) => {
|
||||
const [quotesData, setQuotesData] = useState({ hasMore: true, rows: [], totalItems: 0 })
|
||||
const manageQuotes = props => {
|
||||
const [quotesData, setQuotesData] = useState({
|
||||
hasMore: true,
|
||||
rows: [],
|
||||
totalItems: 0
|
||||
})
|
||||
const [isLoadingQuotes, setLoadingQuotes] = useState(true)
|
||||
const [pageQuotes, setPageQuotes] = useState(1)
|
||||
|
||||
@ -20,7 +24,9 @@ const manageQuotes = (props) => {
|
||||
|
||||
const getQuotesData = async () => {
|
||||
setLoadingQuotes(true)
|
||||
const { data } = await api.get(`/admin/quotes?limit=20page=${pageQuotes}`, { headers: { Authorization: props.user.token } })
|
||||
const { data } = await api.get(`/admin/quotes?limit=20page=${pageQuotes}`, {
|
||||
headers: { Authorization: props.user.token }
|
||||
})
|
||||
setQuotesData({
|
||||
hasMore: data.hasMore,
|
||||
rows: [...quotesData.rows, ...data.rows],
|
||||
@ -31,33 +37,48 @@ const manageQuotes = (props) => {
|
||||
|
||||
// Permet la pagination au scroll
|
||||
const observer = useRef()
|
||||
const lastQuoteRef = useCallback((node) => {
|
||||
if (isLoadingQuotes) return
|
||||
if (observer.current) observer.current.disconnect()
|
||||
observer.current = new window.IntersectionObserver((entries) => {
|
||||
if (entries[0].isIntersecting && quotesData.hasMore) {
|
||||
setPageQuotes(pageQuotes + 1)
|
||||
}
|
||||
}, { threshold: 1 })
|
||||
if (node) observer.current.observe(node)
|
||||
}, [isLoadingQuotes, quotesData.hasMore])
|
||||
const lastQuoteRef = useCallback(
|
||||
node => {
|
||||
if (isLoadingQuotes) return
|
||||
if (observer.current) observer.current.disconnect()
|
||||
observer.current = new window.IntersectionObserver(
|
||||
entries => {
|
||||
if (entries[0].isIntersecting && quotesData.hasMore) {
|
||||
setPageQuotes(pageQuotes + 1)
|
||||
}
|
||||
},
|
||||
{ threshold: 1 }
|
||||
)
|
||||
if (node) observer.current.observe(node)
|
||||
},
|
||||
[isLoadingQuotes, quotesData.hasMore]
|
||||
)
|
||||
|
||||
const handleValidationQuote = async (id, isValid) => {
|
||||
try {
|
||||
await api.put(`/admin/quotes/${id}`, { isValid }, { headers: { Authorization: props.user.token } })
|
||||
await api.put(
|
||||
`/admin/quotes/${id}`,
|
||||
{ isValid },
|
||||
{ headers: { Authorization: props.user.token } }
|
||||
)
|
||||
window.location.reload(true)
|
||||
} catch {}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<HeadTag title='Admin - FunctionProject' description="Page d'administration de FunctionProject. Gérer les citations." />
|
||||
<HeadTag
|
||||
title='Admin - FunctionProject'
|
||||
description="Page d'administration de FunctionProject. Gérer les citations."
|
||||
/>
|
||||
|
||||
<div className='container-fluid'>
|
||||
<div className='row justify-content-center'>
|
||||
<div className='col-24 text-center'>
|
||||
<h2>Liste des citations (non validées) : </h2>
|
||||
<p style={{ marginTop: '5px' }}>Total de {quotesData.totalItems} citations.</p>
|
||||
<p style={{ marginTop: '5px' }}>
|
||||
Total de {quotesData.totalItems} citations.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -66,35 +87,72 @@ const manageQuotes = (props) => {
|
||||
<table className='table'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th className='table-row' scope='col'>Citation/Proverbe</th>
|
||||
<th className='table-row' scope='col'>Auteur</th>
|
||||
<th className='table-row' scope='col'>Proposée par</th>
|
||||
<th className='table-row' scope='col'>Valider</th>
|
||||
<th className='table-row' scope='col'>Supprimer</th>
|
||||
<th className='table-row' scope='col'>
|
||||
Citation/Proverbe
|
||||
</th>
|
||||
<th className='table-row' scope='col'>
|
||||
Auteur
|
||||
</th>
|
||||
<th className='table-row' scope='col'>
|
||||
Proposée par
|
||||
</th>
|
||||
<th className='table-row' scope='col'>
|
||||
Valider
|
||||
</th>
|
||||
<th className='table-row' scope='col'>
|
||||
Supprimer
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{quotesData.rows.map((currentQuote, index) => {
|
||||
const quoteJSX = (
|
||||
<>
|
||||
<td className='table-row text-center'>{currentQuote.quote}</td>
|
||||
<td className='table-row text-center'>{currentQuote.author}</td>
|
||||
<td className='table-row text-center'>
|
||||
<Link href='/users/[name]' as={`/users/${currentQuote.user.name}`}>
|
||||
{currentQuote.quote}
|
||||
</td>
|
||||
<td className='table-row text-center'>
|
||||
{currentQuote.author}
|
||||
</td>
|
||||
<td className='table-row text-center'>
|
||||
<Link
|
||||
href='/users/[name]'
|
||||
as={`/users/${currentQuote.user.name}`}
|
||||
>
|
||||
<a>{currentQuote.user.name}</a>
|
||||
</Link>
|
||||
</td>
|
||||
<td onClick={() => handleValidationQuote(currentQuote.id, true)} className='table-row text-center' style={{ cursor: 'pointer' }}>
|
||||
<FontAwesomeIcon icon={faCheck} style={{ width: '1.5rem' }} />
|
||||
<td
|
||||
onClick={() =>
|
||||
handleValidationQuote(currentQuote.id, true)}
|
||||
className='table-row text-center'
|
||||
style={{ cursor: 'pointer' }}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={faCheck}
|
||||
style={{ width: '1.5rem' }}
|
||||
/>
|
||||
</td>
|
||||
<td onClick={() => handleValidationQuote(currentQuote.id, false)} className='table-row text-center' style={{ cursor: 'pointer' }}>
|
||||
<FontAwesomeIcon icon={faTrash} style={{ width: '1.5rem' }} />
|
||||
<td
|
||||
onClick={() =>
|
||||
handleValidationQuote(currentQuote.id, false)}
|
||||
className='table-row text-center'
|
||||
style={{ cursor: 'pointer' }}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={faTrash}
|
||||
style={{ width: '1.5rem' }}
|
||||
/>
|
||||
</td>
|
||||
</>
|
||||
)
|
||||
// Si c'est le dernier élément
|
||||
if (quotesData.rows.length === index + 1) {
|
||||
return <tr key={index} ref={lastQuoteRef}>{quoteJSX}</tr>
|
||||
return (
|
||||
<tr key={index} ref={lastQuoteRef}>
|
||||
{quoteJSX}
|
||||
</tr>
|
||||
)
|
||||
}
|
||||
return <tr key={index}>{quoteJSX}</tr>
|
||||
})}
|
||||
|
Reference in New Issue
Block a user