diff --git a/front/src/api/book/index.ts b/front/src/api/book/index.ts
new file mode 100644
index 0000000..22fd424
--- /dev/null
+++ b/front/src/api/book/index.ts
@@ -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 }
diff --git a/front/src/api/book/types.ts b/front/src/api/book/types.ts
new file mode 100644
index 0000000..8e7c134
--- /dev/null
+++ b/front/src/api/book/types.ts
@@ -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 }
diff --git a/front/src/components/AnnouncementDetails.tsx b/front/src/components/AnnouncementDetails.tsx
index 352b138..b604909 100644
--- a/front/src/components/AnnouncementDetails.tsx
+++ b/front/src/components/AnnouncementDetails.tsx
@@ -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 (
-
+
diff --git a/front/src/hooks/api/useBook.ts b/front/src/hooks/api/useBook.ts
index 71fe6ed..5a1310b 100644
--- a/front/src/hooks/api/useBook.ts
+++ b/front/src/hooks/api/useBook.ts
@@ -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('')
-
- 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