Files
invitation/frontend/src/components/Hosting.tsx
2025-11-02 21:45:12 +02:00

154 lines
6.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import useFetchHosting from "../utils/fetchHosting";
import { useNotification, type NotificationType } from "../NotificationContext";
import { useCookies } from "react-cookie";
import CenteredContainer from "./ChildrenContainer";
import { useState } from "react";
interface ReserveButtonProps {
update: (name: string, id: number) => void,
unreserve: (token: string, id: number) => void,
reservedBy: string,
notify: (message: string, type: NotificationType) => void,
id: number,
}
const ReserveButton: React.FC<ReserveButtonProps> = (props) => {
const { reservedBy, update, id, unreserve, notify } = props;
const [cookie] = useCookies<string>(['userName'])
const [tokenCookie] = useCookies<string>(['apiToken'])
const userName = cookie.userName;
const isReserved = reservedBy !== '';
const handleReserve = async (name: string) => {
try {
await update(name, id);
notify(`Успешно забронировано для ${name}`, 'success');
} catch (error) {
notify(`Не удалось забронировать: ${error instanceof Error ? error.message : 'Unknown error'}`, 'error');
}
};
const handleUnreserve = async () => {
try {
await unreserve(tokenCookie.apiToken, id);
notify(`Удалось разбронировать ${name}`, 'success');
} catch (error) {
notify(`Не удалось разбронировать: ${error instanceof Error ? error.message : 'Unknown error'}`, 'error');
}
}
return (
<>
<button onClick={() => handleReserve(userName)} disabled={isReserved}>
{isReserved ? `${reservedBy}` : 'Занять'}
</button>
{(reservedBy == userName) && (
<button onClick={() => handleUnreserve()} disabled={false}></button>
)}
</>
);
};
const Hosting = () => {
const { data, error, loading, update, unreserveHosting, createHosting } = useFetchHosting();
const [name, setName] = useState('');
const [capacity, setCapacity] = useState('');
const [tokenCookie] = useCookies<string>(['apiToken'])
const notify = useNotification();
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault(); // Prevent the default form submission
if (!name || !capacity) {
notify('Надо заполнить все поля', 'error');
return;
}
try {
await createHosting(tokenCookie.apiToken, name, Number(capacity));
// Reset form fields
setName('');
setCapacity('');
notify('Удалось создать!', 'success');
} catch (error) {
notify(`Не удалось создать: ${error instanceof Error ? error.message : 'Unknown error'}`, 'error');
}
};
return (
<>
<CenteredContainer>
<h2>Поселение</h2>
<p>
Мы готовы приютить в наших 150 квадратах всех. У нас есть 6 спальных мест. При этом, если
вы не хотите тесниться, то рядом с нами есть
<a href="https://www.uoti.net/" target="_blank" rel="noopener noreferrer"> отель</a>, а так же
<a href="https://campingsysma.fi/" target="_blank" rel="noopener noreferrer"> кэмпинг-виллы </a>
(Лучше бронировать заранее если есть надобность. Оба в 1-1,5км от нашего дома).
Спальные места:
</p>
{loading && <div>Loading...</div>}
{error && <div>Error</div>}
{data && (
<div className="table-wrapper scroll-indicator">
<table>
<thead>
<tr>
<th>Размещение</th>
<th>Спальных мест</th>
<th>Бронирование</th>
</tr>
</thead>
<tbody>
{data.furniture && data.furniture.map((item) => (
<tr key={item.id}>
<td>{item.name}</td>
<td>{item.capacity}</td>
<td>
<ReserveButton update={update} reservedBy={item.reservedBy} id={item.id} unreserve={unreserveHosting} notify={notify} />
</td>
</tr>
))}
</tbody>
</table>
<p className="scroll-instruction">Таблицу можно скроллить</p>
</div>
)}
Если вы хотите организовать себе свои спальные места и хотите, чтобы остальные это видели, вы можете добавить свое месо в таблицу.
<form onSubmit={handleSubmit}>
<div>
<label>
Размещение:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>
</label>
</div>
<div>
<label>
Спальных мест:
<input
type="number"
value={capacity}
onChange={(e) => setCapacity(e.target.value)}
required
/>
</label>
</div>
<button type="submit">
{'Создать размещение'}
</button>
</form>
</CenteredContainer>
<br />
</>
);
};
export default Hosting;