DONE: first init
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
.message{
|
||||
font-size: 1000%;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useInterval } from '../../hooks/hooks.jsx';
|
||||
import { fetchData } from '../../fetching/Fetch.js';
|
||||
import { SERVER_URL } from '../../constants.js';
|
||||
import '../CurrentTicketPage/CurrentTicketPage.css';
|
||||
|
||||
export default function CurrentTicketPage() {
|
||||
const [currentTicket, setCurrentTicket] = useState('');
|
||||
const { stationId } = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
fetchCurrentTicket();
|
||||
}, [stationId]);
|
||||
|
||||
useInterval(() => fetchCurrentTicket(), 3000);
|
||||
|
||||
const fetchCurrentTicket = async () => {
|
||||
try {
|
||||
const response = await fetchData(`${SERVER_URL}/api/v1/teller/current-ticket/${stationId}`, 'GET');
|
||||
if (response.success) {
|
||||
if (typeof response.data === 'object' && response.data.message) {
|
||||
setCurrentTicket(response.data.message);
|
||||
} else {
|
||||
setCurrentTicket(response.data.number);
|
||||
}
|
||||
} else {
|
||||
setCurrentTicket('There is no current ticket for this station');
|
||||
console.error('Error fetching current ticket:', response.error);
|
||||
}
|
||||
} catch (error) {
|
||||
setCurrentTicket('There is no current ticket for this station');
|
||||
console.log("Error fetching current ticket:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="text-center mt-5">
|
||||
<h1 className="message">{currentTicket}</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
.center {
|
||||
text-align: center;
|
||||
margin-top: 2%;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { useState } from "react";
|
||||
import ExampleComponent from "../../components/ExampleComponent/ExampleComponent";
|
||||
import ExampleButton from "../../components/ExampleButton/ExampleButton";
|
||||
|
||||
import './Home.css'
|
||||
import { SERVER_URL } from "../../constants";
|
||||
|
||||
export default function Home() {
|
||||
const [message, setMessage] = useState('');
|
||||
|
||||
async function getMessageFromBackend() {
|
||||
const response = await fetch(SERVER_URL + '/api/v1/teller');
|
||||
const body = await response.json();
|
||||
|
||||
setMessage('Got from backend: ' + body.text);
|
||||
}
|
||||
|
||||
return (
|
||||
<main>
|
||||
<ExampleComponent />
|
||||
<div className="center">
|
||||
<ExampleButton text={ "Click to get message from backend" } onClick={ getMessageFromBackend }/>
|
||||
<p>{ message }</p>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
import React, { useState, useEffect } 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 { SERVER_URL } from '../../constants.js';
|
||||
import { Link, useParams } from 'react-router-dom';
|
||||
|
||||
const styles = {
|
||||
stationRow: {
|
||||
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 { stationId} = useParams()
|
||||
|
||||
useEffect(() => {
|
||||
fetchTicketsForTellerStation();
|
||||
}, [ stationId ]);
|
||||
|
||||
useInterval(fetchTicketsForTellerStation, 10000)
|
||||
|
||||
function fetchTicketsForTellerStation() {
|
||||
fetchData(`${ url }stations/${ stationId }/tickets`, 'GET')
|
||||
.then(response => response.data)
|
||||
.then(setTickets)
|
||||
.catch(console.error)
|
||||
}
|
||||
|
||||
function advanceQueue() {
|
||||
fetchData(`${ url }teller/advance-queue/${ stationId }`, 'POST')
|
||||
.then(fetchTicketsForTellerStation)
|
||||
.then(() => setUsedUndo(false))
|
||||
.then(timeOutTeller)
|
||||
.catch(console.error)
|
||||
}
|
||||
|
||||
function undoQueue() {
|
||||
fetchData(`${ url }teller/undo-queue/${ stationId }`, 'POST')
|
||||
.then(fetchTicketsForTellerStation)
|
||||
.then(() => setUsedUndo(true))
|
||||
.catch(console.error)
|
||||
}
|
||||
|
||||
function timeOutTeller() {
|
||||
setTimedOut(true)
|
||||
setTimeout(() => setTimedOut(false), 5000)
|
||||
// Can't advance more often than every 5 seconds.
|
||||
}
|
||||
|
||||
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">
|
||||
<Button
|
||||
variant="primary"
|
||||
style={ { backgroundColor: '#548CA8', color: 'white', borderColor: '#548CA8' } }
|
||||
onClick={ advanceQueue }
|
||||
disabled={ timedOut }
|
||||
>
|
||||
Advance Queue
|
||||
</Button>
|
||||
<Button variant="primary"
|
||||
style={ { backgroundColor: '#548CA8', color: 'white', borderColor: '#548CA8' } }
|
||||
onClick={ undoQueue }
|
||||
disabled={ usedUndo || !hasAssignedTicket }>
|
||||
Undo
|
||||
</Button>
|
||||
<Button variant="primary"
|
||||
style={ { backgroundColor: '#548CA8', color: 'white', borderColor: '#548CA8' } }
|
||||
onClick={ fetchTicketsForTellerStation }>
|
||||
Refresh
|
||||
</Button>
|
||||
<Link to={`/display/${stationId}`} target="_blank" rel="noopener noreferrer">
|
||||
<Button
|
||||
variant="secondary"
|
||||
>
|
||||
Current Ticket
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
<div style={ { marginTop: '20px' } }>
|
||||
<Table striped bordered hover>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Ticket number</th>
|
||||
<th>Service</th>
|
||||
<th>Creation at</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{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>{ticket.service.name}</td>
|
||||
<td>{createdAt.toLocaleString()}</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</Table>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Dropdown, Button } from 'react-bootstrap';
|
||||
import { fetchData } from '../../fetching/Fetch.js';
|
||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
import { SERVER_URL } from '../../constants.js';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
const StationIntroPage = () => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [branches, setBranches] = useState([]);
|
||||
const [selectedBranch, setSelectedBranch] = useState(null);
|
||||
const [stations, setStations] = useState([]);
|
||||
const [selectedStation, setSelectedStation] = useState(null);
|
||||
|
||||
const url = `${ SERVER_URL }/api/v1/`;
|
||||
|
||||
useEffect(() => {
|
||||
fetchData(`${ url }branches/DFLT`, 'GET')
|
||||
.then(response => response.data)
|
||||
.then(setBranches)
|
||||
.catch(console.error)
|
||||
}, []);
|
||||
|
||||
function handleBranchSelect(branch) {
|
||||
setSelectedBranch(branch)
|
||||
fetchData(`${ url }stations/DFLT/${ branch.id }`, 'GET')
|
||||
.then(response => response.data)
|
||||
.then(setStations)
|
||||
.catch(console.error)
|
||||
}
|
||||
|
||||
function handleStationSelect(station) {
|
||||
navigate(`/teller-queue/${ station.id }`)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="text-center mt-5">
|
||||
<div className="border p-3" style={{ maxWidth: '500px', margin: '0 auto' }}>
|
||||
<h1 className="mb-4">Select Branch and Station</h1>
|
||||
|
||||
<Dropdown>
|
||||
<Dropdown.Toggle variant="primary" id="dropdown-branch" style={{ width: '100%' }}>
|
||||
{selectedBranch ? selectedBranch.name : 'Select Branch'}
|
||||
</Dropdown.Toggle>
|
||||
<Dropdown.Menu style={{ width: '100%' }}>
|
||||
{branches.map(branch => (
|
||||
<Dropdown.Item key={branch.id} onClick={() => handleBranchSelect(branch)}>
|
||||
{branch.name}
|
||||
</Dropdown.Item>
|
||||
))}
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
|
||||
{selectedBranch && (
|
||||
<div className="mt-3">
|
||||
<Dropdown>
|
||||
<Dropdown.Toggle variant="primary" id="dropdown-station" style={{ width: '100%' }}>
|
||||
{selectedStation ? selectedStation.name : 'Select Station'}
|
||||
</Dropdown.Toggle>
|
||||
<Dropdown.Menu style={{ width: '100%' }}>
|
||||
{stations.map(station => (
|
||||
<Dropdown.Item key={station.id} onClick={() => handleStationSelect(station)}>
|
||||
{station.name}
|
||||
</Dropdown.Item>
|
||||
))}
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default StationIntroPage;
|
||||
Reference in New Issue
Block a user