Moved useBook to useSend API

This commit is contained in:
Dmitriy Shishkov 2023-07-27 16:56:00 +03:00
parent 2a229c96ba
commit 3bb6809454
Signed by: dm1sh
GPG Key ID: 027994B0AA357688
4 changed files with 57 additions and 61 deletions

View File

@ -0,0 +1,12 @@
import { API_URL } from '../../config'
import { Book, BookResponse } from './types'
const composeBookURL = () => (
API_URL + '/book?'
)
const processBook = (data: BookResponse): Book => {
return data.Success
}
export { composeBookURL, processBook }

View File

@ -0,0 +1,17 @@
import { isObject } from '../../utils/types'
type BookResponse = {
Success: boolean
}
const isBookResponse = (obj: unknown): obj is BookResponse => (
isObject(obj, {
'Success': 'boolean'
})
)
type Book = boolean
export type { BookResponse, Book }
export { isBookResponse }

View File

@ -21,8 +21,10 @@ const styles = {
} as CSSProperties,
}
function AnnouncementDetails({ close, announcement: { id, name, category, bestBy, description, lat, lng, address, metro } }: AnnouncementDetailsProps) {
const { handleBook, status: bookStatus } = useBook(id)
function AnnouncementDetails({ close, announcement: {
id, name, category, bestBy, description, lat, lng, address, metro
} }: AnnouncementDetailsProps) {
const { handleBook, bookButton } = useBook()
return (
<div
@ -62,9 +64,7 @@ function AnnouncementDetails({ close, announcement: { id, name, category, bestBy
</Modal.Body>
<Modal.Footer>
<Button variant='success' onClick={() => void handleBook()}>
{bookStatus || 'Забронировать'}
</Button>
<Button variant='success' onClick={() => void handleBook(id)} {...bookButton} />
</Modal.Footer>
</Modal.Dialog>
</div>

View File

@ -1,10 +1,7 @@
import { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { getToken } from '../../utils/auth'
import { API_URL } from '../../config'
import { useCallback } from 'react'
import { isObject } from '../../utils/types'
import { handleHTTPErrors } from '../../utils'
import { useSendWithButton } from '..'
import { composeBookURL, processBook } from '../../api/book'
type BookResponse = {
Success: boolean
@ -16,59 +13,29 @@ const isBookResponse = (obj: unknown): obj is BookResponse => (
})
)
type BookStatus = '' | 'Загрузка...' | 'Забронировано' | 'Ошибка бронирования'
function useBook() {
const { doSend, button } = useSendWithButton('Забронировать',
'Забронировано',
true,
composeBookURL(),
'POST',
true,
isBookResponse,
processBook
)
function useBook(id: number) {
const navigate = useNavigate()
const [status, setStatus] = useState<BookStatus>('')
const handleBook = async () => {
const token = getToken()
if (token) {
setStatus('Загрузка...')
try {
const res = await fetch(API_URL + '/book', {
method: 'POST',
body: JSON.stringify({
id: id
}),
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'
}
})
handleHTTPErrors(res)
const data: unknown = await res.json()
if (!isBookResponse(data)) {
throw new Error('Malformed server response')
}
if (data.Success === true) {
setStatus('Забронировано')
} else {
throw new Error('Server refused to book')
}
const handleBook = useCallback((id: number) => {
void doSend({
body: JSON.stringify({
id
}),
headers: {
'Content-Type': 'application/json'
}
catch (err) {
setStatus('Ошибка бронирования')
})
}, [doSend])
if (import.meta.env.DEV) {
console.log(err)
}
}
} else {
return navigate('/login')
}
}
return { handleBook, status }
return { handleBook, bookButton: button }
}
export default useBook