some css fix and websocket fix for item update
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
import { HotelProvider, useHotel } from "./HotelContext";
|
||||
import { HotelProvider, useHotel } from "./context/HotelContext";
|
||||
import RoomWidget from "./widget/roomWidget"
|
||||
import ChatWidget from "./widget/chatWidget"
|
||||
import InventoryWidget from "./widget/inventoryWidget";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import "./MainApp.css"
|
||||
import AdminWidget from "./widget/adminWidget";
|
||||
|
||||
export default function MainAppWrapper({resClientId}) {
|
||||
const accessToken = localStorage.getItem("access_tokens");
|
||||
const accessToken = localStorage.getItem("access_tokens");
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<HotelProvider accessToken={accessToken} resClientId={resClientId}>
|
||||
@@ -18,25 +21,29 @@ export default function MainAppWrapper({resClientId}) {
|
||||
|
||||
function MainApp() {
|
||||
const accessToken = localStorage.getItem("access_tokens");
|
||||
const { rooms, conversations, users } = useHotel();
|
||||
const VIEW = {
|
||||
ROOMS: "rooms",
|
||||
INVENTORY: "inventory",
|
||||
ADMIN: "admin",
|
||||
};
|
||||
|
||||
const { rooms } = useHotel();
|
||||
const { conversations } = useHotel();
|
||||
const { users } = useHotel();
|
||||
|
||||
const [view, setView] = useState(VIEW.ROOMS)
|
||||
|
||||
return (
|
||||
<div style={{ padding: "2rem" }}>
|
||||
<h1>Welcome to MyHotel!</h1>
|
||||
<div>
|
||||
<div className="toolbar">
|
||||
<button className="toolbutton" onClick={() => setView(VIEW.ROOMS)}>Rooms</button>
|
||||
<button className="toolbutton" onClick={() => setView(VIEW.INVENTORY)}>Inventory</button>
|
||||
</div>
|
||||
|
||||
<h2>Access token</h2>
|
||||
<pre>{accessToken}</pre>
|
||||
<h3>Rooms: {rooms.length}</h3>
|
||||
<h3>Conversations: {conversations.length}</h3>
|
||||
<h3>Users: {users.length}</h3>
|
||||
<h2>Dashboard</h2>
|
||||
<section className="main">
|
||||
|
||||
|
||||
<RoomWidget roomlist={rooms}/>
|
||||
<ChatWidget convlist={conversations}/>
|
||||
<InventoryWidget/>
|
||||
<AdminWidget/>
|
||||
{view === VIEW.ROOMS && <RoomWidget />}
|
||||
{view === VIEW.INVENTORY && <InventoryWidget />}
|
||||
<ChatWidget convlist={conversations} />
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,23 @@
|
||||
.main {
|
||||
display: grid;
|
||||
grid-template-columns: 70% 30%;
|
||||
height: 80%;
|
||||
}
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
background-color: rgb(160, 149, 199);
|
||||
}
|
||||
|
||||
|
||||
.main > * {
|
||||
min-width: 0; /* prevents overflow bugs */
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
justify-content: space-around;
|
||||
height: 10vh;
|
||||
height: 5vh;
|
||||
}
|
||||
|
||||
.toolbutton {
|
||||
margin: .5rem;
|
||||
height: 80%;
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import {createContext, useContext,
|
||||
useState, useEffect,
|
||||
useRef
|
||||
} from "react";
|
||||
import { API_BASE } from "../config";
|
||||
import { API_BASE } from "../../config";
|
||||
|
||||
const HotelContext = createContext(null);
|
||||
|
||||
@@ -16,6 +16,9 @@ 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({});
|
||||
@@ -55,7 +58,6 @@ export function HotelProvider({ accessToken, children, resClientId}) {
|
||||
|
||||
// CHAT
|
||||
|
||||
|
||||
async function createConversation(name) {
|
||||
|
||||
const payload = {
|
||||
@@ -278,11 +280,24 @@ export function HotelProvider({ accessToken, children, resClientId}) {
|
||||
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);
|
||||
}
|
||||
@@ -290,7 +305,7 @@ export function HotelProvider({ accessToken, children, resClientId}) {
|
||||
|
||||
// --- ADMIN PORTAL ----
|
||||
|
||||
function registerUser(username,password,hotel_ids, displayname) {
|
||||
function registerUser(username, password, hotel_ids, displayname) {
|
||||
|
||||
const payload = {
|
||||
username,
|
||||
@@ -351,10 +366,11 @@ async function addHotelUser(user_id,hotel_ids) {
|
||||
if (!accessToken) return;
|
||||
|
||||
async function load() {
|
||||
const [roomsData, convData, usersData] = await Promise.all([
|
||||
const [roomsData, convData, usersData, itemsData] = await Promise.all([
|
||||
fetchRooms(),
|
||||
fetchConversations(),
|
||||
fetchHotelUsers(),
|
||||
fetchHotelInventory(),
|
||||
|
||||
]);
|
||||
|
||||
@@ -362,7 +378,7 @@ async function addHotelUser(user_id,hotel_ids) {
|
||||
setRooms(roomsData);
|
||||
setConversations(convData);
|
||||
setUsers(usersData);
|
||||
|
||||
SetItems(itemsData);
|
||||
//getHotelList();
|
||||
|
||||
}
|
||||
@@ -370,7 +386,7 @@ async function addHotelUser(user_id,hotel_ids) {
|
||||
load();
|
||||
|
||||
|
||||
//console.log("USERS 2 =",usersById)
|
||||
console.log("here are hte items" + items)
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -383,7 +399,8 @@ async function addHotelUser(user_id,hotel_ids) {
|
||||
//if (!accessTokenSingle || !clientId) return;
|
||||
|
||||
const ws = new WebSocket(
|
||||
`http://localhost:7080/auth/ws/${accessTokenSingle}`
|
||||
`ws://localhost:7080/auth/ws/${accessTokenSingle}`
|
||||
//`wss://79.137.75.155/hotel-demo/api/auth/ws/${accessTokenSingle}`
|
||||
);
|
||||
|
||||
wsRef.current = ws;
|
||||
@@ -423,6 +440,7 @@ async function addHotelUser(user_id,hotel_ids) {
|
||||
users,
|
||||
usersById,
|
||||
clientId,
|
||||
items,
|
||||
|
||||
fetchHotelUsers,
|
||||
updateRoomStatus,
|
||||
65
src/components/context/RoomContext.jsx
Normal file
65
src/components/context/RoomContext.jsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import {createContext, useContext,
|
||||
useState, useEffect,
|
||||
useRef } from "react";
|
||||
import { API_BASE } from "../../config";
|
||||
|
||||
const RoomContext = createContext(null);
|
||||
|
||||
export function UseRoom() {
|
||||
return useContext(RoomContext);
|
||||
}
|
||||
|
||||
export function RoomProvider({ accessToken, children, resclientid}) {
|
||||
|
||||
const [rooms, setRooms] = useState([]);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
//TODO: update room status function
|
||||
|
||||
useEffect(() => {
|
||||
if (!accessToken) return;
|
||||
|
||||
async function load() {
|
||||
const [roomsData] = await Promise.all([
|
||||
fetchRooms()
|
||||
]);
|
||||
|
||||
setRooms(roomsData);
|
||||
}
|
||||
|
||||
load();
|
||||
})
|
||||
|
||||
return(
|
||||
<RoomContext.Provider
|
||||
value={{
|
||||
rooms,
|
||||
|
||||
|
||||
updateRoomStatus
|
||||
}}
|
||||
></RoomContext.Provider>
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
@@ -40,22 +40,104 @@ export default function Login({ onLogin }) {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: add login button for test1 and test2
|
||||
|
||||
async function LoginTest1() {
|
||||
//e.preventDefault();
|
||||
//setError("");
|
||||
|
||||
const device_id = "147ac10b-58cc-4372-a567-0e02b2c3d479";
|
||||
|
||||
let username = "test1"
|
||||
let password = "test1"
|
||||
|
||||
try {
|
||||
const res = await fetch(`${API_BASE}/auth/create_refresh`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": "react-app",
|
||||
},
|
||||
credentials: "include",
|
||||
body: JSON.stringify({ username, password, device_id }),
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
setError("Invalid credentials or server error.");
|
||||
return;
|
||||
}
|
||||
|
||||
//const data = await res.json(); // server returns short-lived token
|
||||
//localStorage.setItem("access_token", data.access_token);
|
||||
|
||||
if (onLogin) await onLogin(); // notify App to show MainApp
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
setError("Network error.");
|
||||
}
|
||||
}
|
||||
|
||||
async function LoginTest2() {
|
||||
//e.preventDefault();
|
||||
//setError("");
|
||||
|
||||
const device_id = "147ac10b-58cc-4372-a567-0e02b2c3d479";
|
||||
|
||||
let username = "test2"
|
||||
let password = "test2"
|
||||
|
||||
try {
|
||||
const res = await fetch(`${API_BASE}/auth/create_refresh`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": "react-app",
|
||||
},
|
||||
credentials: "include",
|
||||
body: JSON.stringify({ username, password, device_id }),
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
setError("Invalid credentials or server error.");
|
||||
return;
|
||||
}
|
||||
|
||||
//const data = await res.json(); // server returns short-lived token
|
||||
//localStorage.setItem("access_token", data.access_token);
|
||||
|
||||
if (onLogin) await onLogin(); // notify App to show MainApp
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
setError("Network error.");
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
<button type="submit">Login</button>
|
||||
{error && <p style={{ color: "red" }}>{error}</p>}
|
||||
</form>
|
||||
<>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
<button type="submit">Login</button>
|
||||
{error && <p style={{ color: "red" }}>{error}</p>}
|
||||
</form>
|
||||
<div>
|
||||
<button onClick={LoginTest1} >login test 1</button>
|
||||
<button onClick={LoginTest2} >login test 2</button>
|
||||
</div>
|
||||
</>
|
||||
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,46 +1,34 @@
|
||||
.messagebox{
|
||||
|
||||
|
||||
/* Room grid */
|
||||
.roomGrid {
|
||||
margin: 5px;
|
||||
height: 90vh;
|
||||
overflow-y: auto;
|
||||
border-radius: 10px;
|
||||
background-color: var(--card) ;
|
||||
display: grid;
|
||||
padding: 16px;
|
||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
/* Room card */
|
||||
.card {
|
||||
background-color: var(--panel) ;
|
||||
padding: 1rem;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
/* your messages */
|
||||
.msg--mine {
|
||||
align-self: flex-end;
|
||||
background-color: #464b43;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* others */
|
||||
.msg--theirs {
|
||||
align-self: flex-start;
|
||||
background-color: #473f3f;
|
||||
}
|
||||
.grid {
|
||||
display: flex;
|
||||
justify-items: space-around;
|
||||
gap: 1px;
|
||||
background-color: #777777;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
gap: 1px;
|
||||
background-color: #a3a3a3;
|
||||
padding: 5px;
|
||||
|
||||
}
|
||||
|
||||
.card input {
|
||||
width: 90%;
|
||||
box-sizing: border-box; /* important */
|
||||
max-width: 100%; /* prevents overflow */
|
||||
.roomCard input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
|
||||
justify-content: space-between;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
import { useHotel } from "../HotelContext";
|
||||
import { useHotel } from "../context/HotelContext";
|
||||
|
||||
|
||||
export default function AdminWidget() {
|
||||
|
||||
@@ -1,16 +1,89 @@
|
||||
.chatWidget{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.convcard {
|
||||
background-color: brown;
|
||||
.chatWidget {
|
||||
margin :5px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
background: var(--card);
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.convlist {
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: right;
|
||||
background-color: darkcyan;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 0.5rem;
|
||||
padding: 0.75rem;
|
||||
overflow-y: auto;
|
||||
height: 20%;
|
||||
}
|
||||
|
||||
.convcard {
|
||||
padding: 0.5rem 0.75rem;
|
||||
background: var(--panel);
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.convcard:hover {
|
||||
background: var(--border);
|
||||
}
|
||||
|
||||
.senderBox{
|
||||
display: flex;
|
||||
height: 10%;
|
||||
}
|
||||
|
||||
.senderBox * {
|
||||
border: 0px;
|
||||
padding: 0px;
|
||||
|
||||
}
|
||||
|
||||
.textbox{
|
||||
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.sendbutton{
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
|
||||
.messageCard {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
|
||||
background: var(--messageCard);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* Messages */
|
||||
.msg {
|
||||
max-width: 70%;
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-radius: 10px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.msg--mine {
|
||||
align-self: flex-end;
|
||||
background: var(--accent);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.msg--theirs {
|
||||
align-self: flex-start;
|
||||
background: var(--panel);
|
||||
}
|
||||
|
||||
.createConvBox {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.createConvBox > * {
|
||||
|
||||
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useHotel } from "../HotelContext";
|
||||
|
||||
import { useHotel } from "../context/HotelContext";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useRef } from "react";
|
||||
|
||||
@@ -110,17 +111,63 @@ function SenderBox({ conv_id, onSend, disabled }) {
|
||||
};
|
||||
|
||||
return (
|
||||
<div hidden={disabled} className="senderbox">
|
||||
<div hidden={disabled} className="senderBox">
|
||||
<input
|
||||
className="textbox"
|
||||
value={text}
|
||||
onChange={e => setText(e.target.value)}
|
||||
onKeyDown={e => e.key === "Enter" && handleSend() }
|
||||
placeholder="Type a message…"
|
||||
/>
|
||||
<button onClick={handleSend}>Send</button>
|
||||
<button className="sendbutton" onClick={handleSend}>Send</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ConvCard({id, title, onOpenConv}) {
|
||||
return(
|
||||
<div className="convcard" onClick={() => onOpenConv(id)} >
|
||||
<h3>ConvId : {id} </h3>
|
||||
<h3>Name : {title}</h3>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function MessagesBox({ conv_id }) {
|
||||
const { messagesByConvId, usersById, clientId } = useHotel();
|
||||
const messages = messagesByConvId[conv_id] ?? [];
|
||||
|
||||
console.log(messagesByConvId);
|
||||
console.log(usersById);
|
||||
|
||||
if (messages.length === 0) {
|
||||
return <div className="messagesbox empty">No messages</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="messageCard">
|
||||
{messages
|
||||
.slice()
|
||||
.sort((a, b) => new Date(a.sent_at) - new Date(b.sent_at))
|
||||
.map(msg => {
|
||||
const isMine = msg.sender_id === clientId;
|
||||
return (
|
||||
<div key={msg.sent_at}
|
||||
className={`msg ${isMine ? "msg--mine" : "msg--theirs"}`}>
|
||||
<p>
|
||||
<strong>Sender:</strong>{" "}
|
||||
{usersById[msg.sender_id] ?? "Unknown user"}
|
||||
</p>
|
||||
|
||||
<p>{msg.content}</p>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function AddUsersMenu({ convId, usersById, fetchConvUsers, onValidate, onClose }) {
|
||||
const [selected, setSelected] = useState(new Set());
|
||||
|
||||
@@ -197,53 +244,10 @@ function CreateConvMenu({onSend}) {
|
||||
<input
|
||||
value= {nameText}
|
||||
onChange= {element => setNameText(element.target.value)}
|
||||
onKeyDown={e => e.key === "Enter" && handleSend() }
|
||||
placeholder="Ma Conversation"
|
||||
/>
|
||||
<button onClick= {handleSend}>Send</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function ConvCard({id, title, onOpenConv}) {
|
||||
return(
|
||||
<div className="convcard">
|
||||
<h3>ConvId : {id} </h3>
|
||||
<h3>Name : {title}</h3>
|
||||
<p onClick={() => onOpenConv(id)}> GET MESSAAGE</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function MessagesBox({ conv_id }) {
|
||||
const { messagesByConvId, usersById, clientId } = useHotel();
|
||||
const messages = messagesByConvId[conv_id] ?? [];
|
||||
|
||||
console.log(messagesByConvId);
|
||||
console.log(usersById);
|
||||
|
||||
if (messages.length === 0) {
|
||||
return <div className="messagesbox empty">No messages</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="messagebox">
|
||||
{messages
|
||||
.slice()
|
||||
.sort((a, b) => new Date(a.sent_at) - new Date(b.sent_at))
|
||||
.map(msg => {
|
||||
const isMine = msg.sender_id === clientId;
|
||||
return (
|
||||
<div key={msg.sent_at}
|
||||
className={`msg ${isMine ? "msg--mine" : "msg--theirs"}`}>
|
||||
<p>
|
||||
<strong>Sender:</strong>{" "}
|
||||
{usersById[msg.sender_id] ?? "Unknown user"}
|
||||
</p>
|
||||
|
||||
<p>{msg.content}</p>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,2 +1,23 @@
|
||||
|
||||
.grid {
|
||||
margin: 5px ;
|
||||
align-items: start;
|
||||
grid-auto-rows: max-content;
|
||||
height: 90vh;
|
||||
overflow-y: auto;
|
||||
border-radius: 10px;
|
||||
background-color: var(--card) ;
|
||||
padding: 16px;
|
||||
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
||||
gap: 1rem;
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.itemcard {
|
||||
background-color: var(--panel) ;
|
||||
padding: 1rem;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
@@ -1,54 +1,46 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import {HotelProvider, useHotel} from "../HotelContext";
|
||||
import {HotelProvider, useHotel} from "../context/HotelContext";
|
||||
import "./inventoryWidget.css";
|
||||
|
||||
export default function InventoryWidget({}) {
|
||||
const {
|
||||
fetchHotelInventory
|
||||
} = useHotel();
|
||||
//const { fetchHotelInventory } = useHotel();
|
||||
//const [items, setItems] = useState([]);
|
||||
|
||||
const [items, setItems] = useState([]);
|
||||
|
||||
|
||||
/*
|
||||
useEffect(() => {
|
||||
|
||||
async function loadInventory() {
|
||||
const data = await fetchHotelInventory()
|
||||
setItems(data);
|
||||
}
|
||||
|
||||
loadInventory()
|
||||
console.log ("loaded inventory")
|
||||
|
||||
}, [])
|
||||
*/
|
||||
|
||||
const { items } = useHotel();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="grid">
|
||||
{items.map(item => (
|
||||
<ItemCard
|
||||
key={item.id}
|
||||
id={item.id}
|
||||
name={item.name}
|
||||
amount={item.amount}
|
||||
/>
|
||||
|
||||
))}
|
||||
</div>
|
||||
<div>
|
||||
<CreateItemMenu/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="grid">
|
||||
{items.map(item => (
|
||||
<ItemCard
|
||||
key={item.id}
|
||||
id={item.id}
|
||||
name={item.name}
|
||||
amount={item.amount}
|
||||
/>
|
||||
))}
|
||||
<CreateItemMenu/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
||||
function ItemCard({id, name, amount}) {
|
||||
const [itemAmount, setItemAmount] = useState(amount);
|
||||
const [editing, setEditing] = useState(false);
|
||||
|
||||
const {updateItemAmount} = useHotel();
|
||||
|
||||
function submit(item_id, item_amount) {
|
||||
@@ -59,10 +51,12 @@ function ItemCard({id, name, amount}) {
|
||||
|
||||
return (
|
||||
<div className="itemcard">
|
||||
<div>{name}</div>
|
||||
<h3>{name}</h3>
|
||||
|
||||
{!editing ?(
|
||||
<p onClick={() => setEditing(true)} /*style={ cursor: "pointer" }*/>Amount :{amount}</p>
|
||||
<h5 onClick={() => setEditing(true)} >
|
||||
Amount :{amount}
|
||||
</h5>
|
||||
):(
|
||||
<div>
|
||||
<input
|
||||
@@ -74,10 +68,8 @@ function ItemCard({id, name, amount}) {
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
//TODO: same pb as convlist, update when typing in the create menu
|
||||
@@ -86,25 +78,23 @@ function CreateItemMenu() {
|
||||
const [itemAmount, setItemAmount] = useState(0);
|
||||
const {createItem} = useHotel();
|
||||
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (!itemName.trim() | !itemAmount.trim() ) return;
|
||||
|
||||
createItem(itemName, itemAmount);
|
||||
|
||||
}
|
||||
|
||||
return(
|
||||
<div>
|
||||
<div className="itemcard" >
|
||||
<input
|
||||
type="text"
|
||||
onChange={element => setItemName(element.target.value)}
|
||||
placeholder="Nom de l'objet"
|
||||
type="text"
|
||||
onChange={element => setItemName(element.target.value)}
|
||||
placeholder="Nom de l'objet"
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
onChange={element => setItemAmount(element.target.value)}
|
||||
placeholder="Montant d'objet(s)"
|
||||
type="text"
|
||||
onChange={element => setItemAmount(element.target.value)}
|
||||
placeholder="Montant d'objet(s)"
|
||||
/>
|
||||
<button onClick={handleSubmit}>Creer</button>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
|
||||
import "./RoomWidget.css";
|
||||
import { useHotel } from "../HotelContext";
|
||||
import { useHotel } from "../context/HotelContext";
|
||||
import { useState } from "react";
|
||||
export default function RoomWidget({ roomlist }) {
|
||||
|
||||
|
||||
|
||||
|
||||
export default function RoomWidget({}) {
|
||||
|
||||
const { rooms } = useHotel();
|
||||
|
||||
return (
|
||||
<div className="grid">
|
||||
{roomlist.map(room => (
|
||||
<div className="roomGrid">
|
||||
{rooms.map(room => (
|
||||
<RoomCard
|
||||
key={room.id}
|
||||
id = {room.id}
|
||||
@@ -19,8 +24,6 @@ export default function RoomWidget({ roomlist }) {
|
||||
}
|
||||
|
||||
function RoomCard({ number, status ,id}) {
|
||||
|
||||
|
||||
//FIXME: this shouldn't use hotel context, instead : set the state once on load
|
||||
const { updateRoomStatus } = useHotel();
|
||||
const [editing, setEdtiting] = useState(false);
|
||||
|
||||
Reference in New Issue
Block a user