Add loading context and loading bar component; integrate axios for API calls and update routing for locker registration
This commit is contained in:
@@ -15,7 +15,7 @@ function FormBox({ title, children, alt = false }) {
|
||||
className={clsx(
|
||||
alt &&
|
||||
"bg-surface dark:bg-surface-dark border-3 border-secondary-variant dark:border-secondary-variant-dark",
|
||||
"font-body absolute left-11 -top-4 bg-secondary dark:bg-secondary-dark text-primary dark:text-primary-dark font-medium py-1 px-4 rounded-full"
|
||||
"font-body absolute left-11 -top-4 bg-secondary dark:bg-secondary-dark text-primary dark:text-primary-dark font-medium py-1 px-4 rounded-full z-20"
|
||||
)}
|
||||
>
|
||||
{title}
|
||||
|
||||
15
src/components/LoadingBar.jsx
Normal file
15
src/components/LoadingBar.jsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
function LoadingBar() {
|
||||
return (
|
||||
<div className="h-1 bg-grey relative overflow-hidden">
|
||||
<motion.div
|
||||
className="bg-primary dark:bg-primary-dark w-full h-full rounded-sm absolute"
|
||||
animate={{ x: ["-100%", "100%"] }}
|
||||
transition={{ repeat: Infinity, duration: 2, ease: "anticipate" }}
|
||||
></motion.div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default LoadingBar;
|
||||
@@ -1,69 +0,0 @@
|
||||
import { createContext, useState } from "react";
|
||||
import { CircleAlert, X, CircleX, Check } from "lucide-react";
|
||||
import { toTitleCase } from "../util/util";
|
||||
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export const ToastContext = createContext();
|
||||
|
||||
export const ToastProvider = ({ children }) => {
|
||||
const [toast, setToast] = useState({ show: false, message: "", type: "" });
|
||||
|
||||
const playAudio = (type) => {
|
||||
let audioSrc;
|
||||
if(type === "warning") audioSrc = "/audio/warning.mp3";
|
||||
else if (type === "error") audioSrc = "/audio/error.mp3";
|
||||
|
||||
if (audioSrc) {
|
||||
const audio = new Audio(audioSrc);
|
||||
audio.play().catch((error) => console.error("Error playing audio:", error));
|
||||
}
|
||||
};
|
||||
|
||||
const showToast = (message, type) => {
|
||||
playAudio(type);
|
||||
setToast({ show: true, message, type });
|
||||
setTimeout(() => {
|
||||
setToast({ show: false, message: "", type: "" });
|
||||
}, 7000);
|
||||
};
|
||||
let toastIcon;
|
||||
let surfaceColor;
|
||||
let borderColor;
|
||||
if(toast.type === "warning") {
|
||||
toastIcon = <CircleAlert size={30} fill="#EA7000" stroke="#FDF1E5" />;
|
||||
surfaceColor = "bg-warning-surface";
|
||||
borderColor = "border-warning";
|
||||
} else if(toast.type === "success") {
|
||||
toastIcon = <Check size={30} color="green"/>;
|
||||
surfaceColor = "bg-success-surface";
|
||||
borderColor = "border-success";
|
||||
} else if (toast.type === "error") {
|
||||
toastIcon = <CircleX size={30} fill="#E5254B" stroke="#FCE9ED" />;
|
||||
surfaceColor = "bg-error-surface";
|
||||
borderColor = "border-error";
|
||||
}
|
||||
|
||||
return (
|
||||
<ToastContext.Provider value={ showToast }>
|
||||
{children}
|
||||
{toast.show && (
|
||||
<div
|
||||
className={`fixed bottom-10 right-5 px-5 py-2 ${surfaceColor} border-2 border-l-8 ${borderColor} rounded-xl font-medium text-onToast z-10 flex gap-5 items-center animate-[slideIn_0.5s]`}
|
||||
role="alert"
|
||||
>
|
||||
{toastIcon}
|
||||
<div>
|
||||
<div className="text-lg text-onToast">{toTitleCase(toast.type)}</div>
|
||||
<div className="text-sm font-body">{toast.message}</div>
|
||||
</div>
|
||||
<X onClick={() => setToast({ show: false, message: "", type: "" })}/>
|
||||
</div>
|
||||
)}
|
||||
</ToastContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
ToastProvider.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
Reference in New Issue
Block a user