Files
hotel-demo-front/src/components/context/HotelContext.jsx
Romain Mallard ba755561e6
All checks were successful
Deploy React / build-and-deploy (push) Successful in 16s
hiccups 2
2026-03-05 10:03:44 +01:00

461 lines
9.3 KiB
JavaScript

import {createContext, useContext,
useState, useEffect,
useRef
} from "react";
import { API_BASE } from "../../config";
const HotelContext = createContext(null);
export function useHotel() {
return useContext(HotelContext);
}
export function HotelProvider({ accessToken, children, resClientId}) {
const [rooms, setRooms] = useState([]);
const [conversations, setConversations] = useState([]);
const [messagesByConvId, setMessagesByConvId] = useState({});
const [items, SetItems] = useState([]);
const [users, setUsers] = useState([]);
const [usersById, setUsersById] = useState({});
const [clientId, setClientId] = useState(resClientId|| null);
const tokens = JSON.parse(accessToken);
const accessTokenSingle = tokens[0];
const wsRef = useRef(null);
// --- API FUNCTIONS ---
// ROOMS
async function fetchRooms() {
const res = await fetch( `${API_BASE}/rooms/rooms`, {
headers: { Authorization: `Bearer ${accessTokenSingle}` },
});
return res.json();
}
async function updateRoomStatus(roomId, status) {
await fetch(`${API_BASE}/rooms/clean_db_update/${roomId}`, {
method: "PUT",
headers: {
Authorization: `Bearer ${accessTokenSingle}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ status }),
});
// refresh cached rooms
//const updated = await fetchRooms();
//setRooms(updated);
}
// CHAT
async function createConversation(name) {
const payload = {
name
};
const res = await fetch(`${API_BASE}/chat/create_conversation`, {
method: "POST",
headers: {
Authorization: `Bearer ${accessTokenSingle}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
}
function appendMessage(msg) {
setMessagesByConvId(prev => ({
...prev,
[msg.conv_id]: [
...(prev[msg.conv_id] ?? []),
msg,
],
}));
}
async function fetchConversations() {
const res = await fetch(`${API_BASE}/chat/get_conv`, {
method: "POST",
headers: {
Authorization: `Bearer ${accessTokenSingle}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
conv_id: 4,
timestamp: "2025-09-25 11:05:33",
}),
});
return res.json();
}
async function fetchMessages({ conv_id }) {
const payload = {
conv_id,
timestamp: "2025-09-25 11:05:33",
};
//console.log(JSON.stringify(payload));
const res = await fetch(`${API_BASE}/chat/get_message`, {
method: "POST",
headers: {
Authorization: `Bearer ${accessTokenSingle}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
const messages = await res.json();
setMessagesByConvId(prev => ({
...prev,
[conv_id]: messages,
}));
return messages;
//return res.json
}
async function fetchConvUsers({ conv_id }) {
const payload = {
conv_id,
timestamp: "2025-09-25 11:05:33",
};
//console.log(JSON.stringify(payload));
const res = await fetch(`${API_BASE}/chat/get_conv_users/${conv_id}`, {
method: "POST",
headers: {
Authorization: `Bearer ${accessTokenSingle}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
return res.json();
//return res.json
}
async function sendMessage({ conv_id, message }) {
if (!conv_id) {
console.log("conv_id null at sendMessage")
return
};
const payload = {
conv_id,
message
};
//console.log(JSON.stringify(payload));
const res = await fetch(`${API_BASE}/chat/send_message`, {
method: "POST" ,
headers: {
Authorization: `Bearer ${accessTokenSingle}`,
"Content-Type" : "application/json",
},
body: JSON.stringify(payload),
})
}
async function addUserToConv({ conv_id, users}) {
if (!conv_id || !users) {
console.log("error in convs or user to add")
};
const payload = {
conv_id,
users
};
const res = await fetch(`${API_BASE}/chat/add_users_conv`, {
method: "PUT" ,
headers: {
Authorization: `Bearer ${accessTokenSingle}`,
"Content-Type" : "application/json",
},
body: JSON.stringify(payload),
})
}
async function preloadMessages(conversations) {
for (const conv of conversations) {
await fetchMessages({ conv_id: conv.id });
}
}
// INVENTORY
async function fetchHotelInventory() {
const res = await fetch ( `${API_BASE}/inventory/get_item/`, {
headers: { Authorization: `Bearer ${accessTokenSingle}`},
});
console.log ("fetched inventory")
return res.json()
}
async function updateItemAmount(item_id, item_amount) {
const res = await fetch ( `${API_BASE}/inventory/update_item/${item_id}/${item_amount}`,
{
method: "PUT",
headers: { Authorization: `Bearer ${accessTokenSingle}` }
});
}
async function createItem(item_name, item_amount){
const res = await fetch ( `${API_BASE}/inventory/add_item/${item_name}/${item_amount}`,
{
method:"POST",
headers: { Authorization: `Bearer ${accessTokenSingle}` }
});
}
async function fetchHotelUsers() {
const res = await fetch(`${API_BASE}/chat/hotel_users`, {
method: "POST",
headers: {
Authorization: `Bearer ${accessTokenSingle}`,
"Content-Type": "application/json",
},
});
const users = await res.json();
const map = {};
for (const u of users) {
map[u.id] = u.username;
}
setUsersById(map);
// setUsers(users)
return users;
}
// --- WS DISPATCH MESSAGE ----
function handleWsMessage(msg) {
console.log("websocket message is :" + msg.event_type, typeof msg.event_type);
switch (msg.event_type) {
case "room_update": {
setRooms(prev =>
prev.map(r =>
r.id === msg.room_id
? { ...r, status: msg.status }
: r
)
);
break;
}
case "item_update": {
SetItems(prev =>
prev.map(i =>
i.id === msg.item_id
? { ...i, amount: msg.number }
: i
)
);
break;
}
case "chat_message": {
appendMessage(msg);
break;
}
default:
console.warn("Unhandled WS message bruuuuh:", msg);
}
}
// --- ADMIN PORTAL ----
function registerUser(username, password, hotel_ids, displayname) {
const payload = {
username,
password,
hotel_ids,
displayname
}
console.log("Reg")
const res = fetch(`${API_BASE}/auth/register`, {
method: "PUT",
headers: {"Content-Type": "application/json"},
body: JSON.stringify(payload),
}
)
}
async function getHotelList() {
const res = await fetch(`${API_BASE}/auth/get_hotels`,
{
method: "GET",
headers: {"Content-Type": "application/json"},
}
)
const result = await res.json();
console.log("all result " + result);
return result;
}
async function addHotelUser(user_id,hotel_ids) {
const payload = {
user_id: parseInt(user_id),
hotel_ids,
}
const res = await fetch(`${API_BASE}/auth/add_hotel_user`,
{
method: "PUT",
headers: {"Content-Type": "application/json"},
body: JSON.stringify(payload),
}
)
}
// --- INITIAL DATA LOADING ---
useEffect(() => {
if (!accessToken) return;
async function load() {
const [roomsData, convData, usersData, itemsData] = await Promise.all([
fetchRooms(),
fetchConversations(),
fetchHotelUsers(),
fetchHotelInventory(),
]);
setClientId(resClientId);
setRooms(roomsData);
setConversations(convData);
setUsers(usersData);
SetItems(itemsData);
//getHotelList();
}
load();
console.log("here are hte items" + items)
}, []);
useEffect(() => {
if (conversations.length === 0) return;
preloadMessages(conversations);
}, [conversations]);
useEffect(() => {
//if (!accessTokenSingle || !clientId) return;
const ws = new WebSocket(
//`ws://localhost:7080/auth/ws/${accessTokenSingle}`
`wss://79.137.75.155/hotel-demo/api/auth/ws/${accessTokenSingle}`
);
wsRef.current = ws;
ws.onopen = () => {
console.log("WS connected");
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
console.log("WS :", msg);
handleWsMessage(msg);
};
ws.onerror = (err) => {
console.error("WS error", err);
};
ws.onclose = () => {
console.log("WS disconnected");
};
return () => {
ws.close();
};
}, [accessTokenSingle]);
return (
<HotelContext.Provider
value={{
rooms,
conversations,
messagesByConvId,
users,
usersById,
clientId,
items,
fetchHotelUsers,
updateRoomStatus,
fetchMessages, fetchConvUsers, sendMessage,
addUserToConv, createConversation,
fetchHotelInventory, updateItemAmount, createItem,
registerUser,
getHotelList, addHotelUser,
}}
>
{children}
</HotelContext.Provider>
);
}