DONE: queue management for customer side to get queue number, add logo to teller display, advertisement module
This commit is contained in:
@@ -1,107 +1,203 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { Button, Table } from 'react-bootstrap';
|
||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
import { useInterval } from '../../hooks/hooks.jsx';
|
||||
import { fetchData } from '../../fetching/Fetch.js'
|
||||
import { fetchData } from '../../fetching/Fetch.js';
|
||||
import { SERVER_URL } from '../../constants.js';
|
||||
import { Link, useParams } from 'react-router-dom';
|
||||
import { Link, useLocation, useParams } from 'react-router-dom';
|
||||
import { UserContext } from '../../context/UserContext.jsx';
|
||||
import { getActiveStation, saveActiveStation } from '../../utils/activeStation.js';
|
||||
|
||||
const styles = {
|
||||
stationRow: {
|
||||
backgroundColor: "#ADD8E6",
|
||||
}
|
||||
backgroundColor: '#ADD8E6',
|
||||
},
|
||||
};
|
||||
|
||||
export default function ShowQueuesForTellerPage() {
|
||||
const url = `${ SERVER_URL }/api/v1/`;
|
||||
const [ tickets, setTickets ] = useState([]);
|
||||
const [ usedUndo, setUsedUndo ] = useState(false)
|
||||
const [ timedOut, setTimedOut ] = useState(false)
|
||||
const url = `${SERVER_URL}/api/v1/`;
|
||||
const [tickets, setTickets] = useState([]);
|
||||
const [usedUndo, setUsedUndo] = useState(false);
|
||||
const [timedOut, setTimedOut] = useState(false);
|
||||
const [stationLabel, setStationLabel] = useState(null);
|
||||
|
||||
const { stationId } = useParams();
|
||||
const location = useLocation();
|
||||
const { user } = useContext(UserContext);
|
||||
const tenantCode = user?.tenantCode;
|
||||
|
||||
const { stationId} = useParams()
|
||||
|
||||
useEffect(() => {
|
||||
fetchTicketsForTellerStation();
|
||||
}, [ stationId ]);
|
||||
}, [stationId]);
|
||||
|
||||
useInterval(fetchTicketsForTellerStation, 10000)
|
||||
useEffect(() => {
|
||||
const fromNav = location.state;
|
||||
if (fromNav?.station?.name) {
|
||||
const next = {
|
||||
stationId: Number(stationId),
|
||||
stationName: fromNav.station.name,
|
||||
branchId: fromNav.branch?.id ?? null,
|
||||
branchName: fromNav.branch?.name ?? null,
|
||||
};
|
||||
saveActiveStation(next);
|
||||
setStationLabel(next);
|
||||
return;
|
||||
}
|
||||
|
||||
const fromSession = getActiveStation(stationId);
|
||||
if (fromSession?.stationName) {
|
||||
setStationLabel(fromSession);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tenantCode) {
|
||||
setStationLabel({ stationId: Number(stationId), stationName: `Station ${stationId}` });
|
||||
return;
|
||||
}
|
||||
|
||||
fetchData(`${url}branches/${encodeURIComponent(tenantCode)}`, 'GET')
|
||||
.then(({ data, success }) => {
|
||||
if (!success || !Array.isArray(data)) {
|
||||
setStationLabel({
|
||||
stationId: Number(stationId),
|
||||
stationName: `Station ${stationId}`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
for (const branch of data) {
|
||||
const station = branch.tellerStations?.find(
|
||||
(item) => Number(item.id) === Number(stationId)
|
||||
);
|
||||
if (station) {
|
||||
const next = {
|
||||
stationId: Number(stationId),
|
||||
stationName: station.name,
|
||||
branchId: branch.id,
|
||||
branchName: branch.name,
|
||||
};
|
||||
saveActiveStation(next);
|
||||
setStationLabel(next);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setStationLabel({
|
||||
stationId: Number(stationId),
|
||||
stationName: `Station ${stationId}`,
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
setStationLabel({
|
||||
stationId: Number(stationId),
|
||||
stationName: `Station ${stationId}`,
|
||||
});
|
||||
});
|
||||
}, [stationId, tenantCode, location.state, url]);
|
||||
|
||||
useInterval(fetchTicketsForTellerStation, 10000);
|
||||
|
||||
function fetchTicketsForTellerStation() {
|
||||
fetchData(`${ url }stations/${ stationId }/tickets`, 'GET')
|
||||
.then(response => response.data)
|
||||
fetchData(`${url}stations/${stationId}/tickets`, 'GET')
|
||||
.then((response) => response.data)
|
||||
.then(setTickets)
|
||||
.catch(console.error)
|
||||
.catch(console.error);
|
||||
}
|
||||
|
||||
function advanceQueue() {
|
||||
fetchData(`${ url }teller/advance-queue/${ stationId }`, 'POST')
|
||||
fetchData(`${url}teller/advance-queue/${stationId}`, 'POST')
|
||||
.then(fetchTicketsForTellerStation)
|
||||
.then(() => setUsedUndo(false))
|
||||
.then(timeOutTeller)
|
||||
.catch(console.error)
|
||||
.catch(console.error);
|
||||
}
|
||||
|
||||
function undoQueue() {
|
||||
fetchData(`${ url }teller/undo-queue/${ stationId }`, 'POST')
|
||||
fetchData(`${url}teller/undo-queue/${stationId}`, 'POST')
|
||||
.then(fetchTicketsForTellerStation)
|
||||
.then(() => setUsedUndo(true))
|
||||
.catch(console.error)
|
||||
.catch(console.error);
|
||||
}
|
||||
|
||||
function timeOutTeller() {
|
||||
setTimedOut(true)
|
||||
setTimeout(() => setTimedOut(false), 5000)
|
||||
setTimedOut(true);
|
||||
setTimeout(() => setTimedOut(false), 5000);
|
||||
// Can't advance more often than every 5 seconds.
|
||||
}
|
||||
|
||||
const hasAssignedTicket = tickets.some(ticket => ticket.station?.id == stationId)
|
||||
const hasAssignedTicket = tickets.some((ticket) => ticket.station?.id == stationId);
|
||||
|
||||
return (
|
||||
<div className="text-center mt-5">
|
||||
<h1>Queues</h1>
|
||||
<div className="d-flex gap-2 justify-content-center">
|
||||
{stationLabel ? (
|
||||
<p className="mb-3" style={{ fontSize: '1.25rem', color: '#334257' }}>
|
||||
<strong>{stationLabel.stationName}</strong>
|
||||
{stationLabel.branchName ? (
|
||||
<span className="text-muted"> · {stationLabel.branchName}</span>
|
||||
) : null}
|
||||
</p>
|
||||
) : null}
|
||||
<div className="d-flex gap-2 justify-content-center flex-wrap">
|
||||
<Button
|
||||
variant="primary"
|
||||
style={ { backgroundColor: '#548CA8', color: 'white', borderColor: '#548CA8' } }
|
||||
onClick={ advanceQueue }
|
||||
disabled={ timedOut }
|
||||
style={{ backgroundColor: '#548CA8', color: 'white', borderColor: '#548CA8' }}
|
||||
onClick={advanceQueue}
|
||||
disabled={timedOut}
|
||||
>
|
||||
Advance Queue
|
||||
Nombor Giliran Seterusnya
|
||||
</Button>
|
||||
<Button variant="primary"
|
||||
style={ { backgroundColor: '#548CA8', color: 'white', borderColor: '#548CA8' } }
|
||||
onClick={ undoQueue }
|
||||
disabled={ usedUndo || !hasAssignedTicket }>
|
||||
Undo
|
||||
<Button
|
||||
variant="primary"
|
||||
style={{ backgroundColor: '#548CA8', color: 'white', borderColor: '#548CA8' }}
|
||||
onClick={undoQueue}
|
||||
disabled={usedUndo || !hasAssignedTicket}
|
||||
>
|
||||
Patah balik
|
||||
</Button>
|
||||
<Button variant="primary"
|
||||
style={ { backgroundColor: '#548CA8', color: 'white', borderColor: '#548CA8' } }
|
||||
onClick={ fetchTicketsForTellerStation }>
|
||||
Refresh
|
||||
<Button
|
||||
variant="primary"
|
||||
style={{ backgroundColor: '#548CA8', color: 'white', borderColor: '#548CA8' }}
|
||||
onClick={fetchTicketsForTellerStation}
|
||||
>
|
||||
Muat semula
|
||||
</Button>
|
||||
<Link to={`/display/${stationId}`} target="_blank" rel="noopener noreferrer">
|
||||
<Button
|
||||
variant="secondary"
|
||||
>
|
||||
Current Ticket
|
||||
</Button>
|
||||
<Button variant="secondary">Tiket semasa</Button>
|
||||
</Link>
|
||||
{tenantCode && stationLabel?.branchId ? (
|
||||
<Link
|
||||
to={`/display/branch/${encodeURIComponent(tenantCode)}/${stationLabel.branchId}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Button variant="secondary">Paparan TV</Button>
|
||||
</Link>
|
||||
) : null}
|
||||
</div>
|
||||
<div style={ { marginTop: '20px' } }>
|
||||
<div style={{ marginTop: '20px' }}>
|
||||
<Table striped bordered hover>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Ticket number</th>
|
||||
<th>Service</th>
|
||||
<th>Creation at</th>
|
||||
<th>Nombor tiket</th>
|
||||
<th>Perkhidmatan</th>
|
||||
<th>Dibuat pada</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{tickets.map((ticket, index) => {
|
||||
{tickets.map((ticket, index) => {
|
||||
const createdAt = new Date(ticket.createdAt);
|
||||
return (
|
||||
<tr key={index}>
|
||||
<td style={ticket.station?.id == stationId ? styles.stationRow : {}}>{ticket.number}</td>
|
||||
<td
|
||||
style={
|
||||
ticket.station?.id == stationId
|
||||
? styles.stationRow
|
||||
: {}
|
||||
}
|
||||
>
|
||||
{ticket.number}
|
||||
</td>
|
||||
<td>{ticket.service.name}</td>
|
||||
<td>{createdAt.toLocaleString()}</td>
|
||||
</tr>
|
||||
@@ -111,5 +207,5 @@ export default function ShowQueuesForTellerPage() {
|
||||
</Table>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user