392 lines
7.9 KiB
JavaScript
392 lines
7.9 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 [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 "chat_message": {
|
|
appendMessage(msg);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
console.warn("Unhandled WS message bruuuuh:", msg);
|
|
}
|
|
}
|
|
|
|
|
|
// --- WS USE EFFECT ----
|
|
|
|
|
|
|
|
// --- INITIAL DATA LOADING ---
|
|
useEffect(() => {
|
|
if (!accessToken) return;
|
|
|
|
async function load() {
|
|
const [roomsData, convData, usersData] = await Promise.all([
|
|
fetchRooms(),
|
|
fetchConversations(),
|
|
fetchHotelUsers(),
|
|
|
|
]);
|
|
|
|
setClientId(resClientId);
|
|
setRooms(roomsData);
|
|
setConversations(convData);
|
|
setUsers(usersData);
|
|
|
|
|
|
|
|
}
|
|
|
|
load();
|
|
|
|
|
|
//console.log("USERS 2 =",usersById)
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (conversations.length === 0) return;
|
|
|
|
preloadMessages(conversations);
|
|
}, [conversations]);
|
|
|
|
useEffect(() => {
|
|
//if (!accessTokenSingle || !clientId) return;
|
|
|
|
const ws = new WebSocket(
|
|
`http://localhost:7080/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,
|
|
updateRoomStatus,
|
|
fetchMessages,
|
|
fetchConvUsers,
|
|
sendMessage,
|
|
fetchHotelUsers,
|
|
addUserToConv,
|
|
createConversation,
|
|
fetchHotelInventory,
|
|
updateItemAmount,
|
|
createItem
|
|
}}
|
|
>
|
|
{children}
|
|
</HotelContext.Provider>
|
|
);
|
|
}
|
|
|