Skip to content
This repository has been archived by the owner on Dec 18, 2024. It is now read-only.

Commit

Permalink
feat(match): ux overhaul (#439)
Browse files Browse the repository at this point in the history
* fix(match): permanent scroll bar in FF

* fix(scanner): ignore ISBNs when blids found

* fix(scanner): wait for alert-close before countdown

* feat(scanner): don't say 'error'

* feat(scanner): tell users not to accept ugly books

* feat(scanner): tell users not to accept ugly books

* feat(scanner): scroll countdown into view

* feat(usermatchdetail): scan-button blue on click

* feat(manualreg): improve buttons
  • Loading branch information
LarsSelbekk authored Jun 18, 2024
1 parent 4d50aeb commit 9e51e20
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 32 deletions.
12 changes: 10 additions & 2 deletions src/components/CountdownToRedirect.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LinearProgress, Box, Typography } from "@mui/material";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import { useEffect, useRef, useState } from "react";

const CountdownToRedirect = ({
path,
Expand All @@ -11,6 +11,14 @@ const CountdownToRedirect = ({
}) => {
const [progress, setProgress] = useState(100);
const router = useRouter();
const elementRef = useRef<HTMLElement>(null);

useEffect(() => {
elementRef.current?.scrollIntoView({
behavior: "smooth",
block: "center",
});
}, []);

useEffect(() => {
const interval = setInterval(() => {
Expand All @@ -30,7 +38,7 @@ const CountdownToRedirect = ({
}, [path, router, seconds]);

return (
<Box sx={{ width: "100%", mt: 1 }}>
<Box sx={{ width: "100%", mt: 1 }} ref={elementRef}>
<Typography variant="h6" sx={{ mb: 2, textAlign: "center" }}>
Du blir videresendt om {Math.ceil((progress / 100) * seconds)}{" "}
sekunder...
Expand Down
2 changes: 1 addition & 1 deletion src/components/OrderHistory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ const OrderHistory = ({ orders }: { orders: Order[] }) => {
width: "80%",
display: "flex",
flexDirection: "column",
overflowY: "scroll",
overflowY: "auto",
}}
>
<Typography
Expand Down
24 changes: 12 additions & 12 deletions src/components/matches/Scanner/ManualRegistrationModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const ManualRegistrationModal = ({
}) => {
const [manualInput, setManualInput] = useState("");
return (
<Dialog open={open}>
<Dialog open={open} onClose={handleClose}>
<DialogContent>
<Stack>
<Typography variant="h4">Manuell registrering</Typography>
Expand All @@ -43,19 +43,9 @@ const ManualRegistrationModal = ({
</Stack>
</DialogContent>
<DialogActions>
<Button
startIcon={<InputRounded />}
color={"success"}
variant={"outlined"}
onClick={() => {
handleSubmit(manualInput);
}}
>
Bekreft
</Button>
<Button
color={"info"}
variant="contained"
variant="outlined"
startIcon={<Close />}
onClick={() => {
setManualInput("");
Expand All @@ -64,6 +54,16 @@ const ManualRegistrationModal = ({
>
Lukk
</Button>
<Button
startIcon={<InputRounded />}
color={"success"}
variant={"outlined"}
onClick={() => {
handleSubmit(manualInput);
}}
>
Bekreft
</Button>
</DialogActions>
</Dialog>
);
Expand Down
56 changes: 40 additions & 16 deletions src/components/matches/Scanner/ScannerModal.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Close, InputRounded } from "@mui/icons-material";
import { AlertColor, Box, Button, Card, Modal, Stack } from "@mui/material";
import Typography from "@mui/material/Typography";
import { Scanner } from "@yudiel/react-qr-scanner";
import { Scanner, IDetectedBarcode } from "@yudiel/react-qr-scanner";
import { AxiosResponse } from "axios";
import React, { useEffect, useState } from "react";

Expand Down Expand Up @@ -99,18 +99,52 @@ const ScannerModal = ({
}
} catch (error) {
setFeedback({
text: String(error),
text: error instanceof Error ? error.message : String(error),
severity: "error",
visible: true,
});
}
};

useEffect(() => {
if (open && expectedItems.length === fulfilledItems.length) {
if (
open &&
expectedItems.length === fulfilledItems.length &&
!(feedback.visible && feedback.severity === "info")
) {
handleClose();
}
}, [expectedItems.length, fulfilledItems.length, handleClose, open]);
}, [
expectedItems.length,
fulfilledItems.length,
handleClose,
open,
feedback.visible,
feedback.severity,
]);

const handleCodeDetection = async (
detectedCodes: IDetectedBarcode[],
): Promise<void> => {
const didFindBlid = detectedCodes.some(
(code) => determineScannedTextType(code.rawValue) === TextType.BLID,
);
const codesToProcess = didFindBlid
? detectedCodes.filter(
(code) => determineScannedTextType(code.rawValue) === TextType.BLID,
)
: detectedCodes;

for (const code of codesToProcess) {
await handleRegistration(code.rawValue).catch((error) =>
console.error("Failed to handle scan", error),
);
// Arbitrary delay to somewhat avoid races the backend isn't smart enough to handle
await new Promise((resolve) => {
window.setTimeout(resolve, 250);
});
}
};

return (
<Modal
Expand Down Expand Up @@ -142,17 +176,7 @@ const ScannerModal = ({
constraints={{ facingMode: "environment" }}
formats={["qr_code", "code_128", "ean_8", "ean_13"]}
components={{ torch: true }}
onScan={async (detectedCodes) => {
for (const code of detectedCodes) {
await handleRegistration(code.rawValue).catch((error) =>
console.error("Failed to handle scan", error),
);
// Arbitrary delay to somewhat avoid races the backend isn't smart enough to handle
await new Promise((resolve) => {
window.setTimeout(resolve, 250);
});
}
}}
onScan={handleCodeDetection}
/>
</Box>
<Box width={"90%"}>
Expand All @@ -169,7 +193,7 @@ const ScannerModal = ({
</Box>
<Box
sx={{
overflowY: "scroll",
overflowY: "auto",
maxHeight: "30rem",
mt: "1rem",
}}
Expand Down
3 changes: 2 additions & 1 deletion src/components/matches/UserMatchDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ const UserMatchDetail = ({
Du skal møte en annen elev og utveksle bøker. Det er viktig at den
som mottar bøker scanner hver bok, hvis ikke blir ikke bøkene
registrert som levert, og avsender kan få faktura.
{!isSender && " Hvis en bok er ødelagt, ikke ta den imot."}
</Typography>
</Box>
<MatchHeader>Du skal møte</MatchHeader>
Expand All @@ -127,7 +128,7 @@ const UserMatchDetail = ({
>
<ScannerTutorial />
<Button
sx={{ background: "green" }}
color="success"
startIcon={<QrCodeScannerIcon />}
variant={"contained"}
onClick={() => setScanModalOpen(true)}
Expand Down

0 comments on commit 9e51e20

Please sign in to comment.