Add Toastify customizations to global CSS to reduce need for inline styling.

Improve theme handling in LyricSearch component
This commit is contained in:
2025-07-31 19:53:45 -04:00
parent c513b15d13
commit 7a22d8056b
3 changed files with 59 additions and 49 deletions

View File

@@ -251,3 +251,20 @@ Custom
background-color: rgba(255, 255, 255, 0.9); background-color: rgba(255, 255, 255, 0.9);
} }
/*
Toastify customizations
*/
.Toastify__toast--error {
background-color: rgba(255, 0, 0, 0.5) !important;
color: inherit !important;
}
.Toastify__toast--info {
background-color: rgba(217, 242, 255, 0.8) !important;
color: #000 !important;
}
.Toastify__toast--success {
background-color: rgba(46, 186, 106, 1) !important;
color: inherit !important;
}

View File

@@ -14,39 +14,25 @@ import ContentCopyIcon from '@mui/icons-material/ContentCopy';
import { AutoComplete } from 'primereact/autocomplete'; import { AutoComplete } from 'primereact/autocomplete';
import { API_URL } from '../config'; import { API_URL } from '../config';
const theme = document.documentElement.getAttribute("data-theme")
document.addEventListener('set-theme', (e) => {
const box = document.querySelector("[class*='lyrics-card-']");
let removedClass = "lyrics-card-dark";
let newTheme = e.detail;
if (newTheme !== "light") {
removedClass = "lyrics-card-light";
}
box?.classList.remove(removedClass);
box?.classList.add(`lyrics-card-${newTheme}`);
});
export default function LyricSearch() { export default function LyricSearch() {
const [showLyrics, setShowLyrics] = useState(false); const [showLyrics, setShowLyrics] = useState(false);
return ( return (
<div className="lyric-search"> <div className="lyric-search">
<h2 className="title"> <h2 className="title">
<span>Lyric Search</span> <span>Lyric Search</span>
</h2> </h2>
<div className="card-text my-4"> <div className="card-text my-4">
<label for="lyric-search-input">Search:</label> <label for="lyric-search-input">Search:</label>
<LyricSearchInputField <LyricSearchInputField
id="lyric-search-input" id="lyric-search-input"
placeholder="Artist - Song" placeholder="Artist - Song"
setShowLyrics={setShowLyrics} /> setShowLyrics={setShowLyrics} />
<div id="spinner" className="hidden"> <div id="spinner" className="hidden">
<CircularProgress <CircularProgress
variant="plain" variant="plain"
color="primary" color="primary"
size="md"/></div> size="md" /></div>
</div> </div>
</div> </div>
); );
} }
@@ -61,6 +47,20 @@ export function LyricSearchInputField({ id, placeholder, setShowLyrics }) {
const [excludedSources, setExcludedSources] = useState([]); const [excludedSources, setExcludedSources] = useState([]);
const [lyricsResult, setLyricsResult] = useState(null); const [lyricsResult, setLyricsResult] = useState(null);
const autoCompleteRef = useRef(null); const autoCompleteRef = useRef(null);
const [theme, setTheme] = useState(document.documentElement.getAttribute("data-theme") || "light");
useEffect(() => {
const handler = (e) => {
const newTheme = e.detail;
setTheme(newTheme);
};
document.addEventListener('set-theme', handler);
return () => {
document.removeEventListener('set-theme', handler);
};
}, []);
// Typeahead: fetch suggestions // Typeahead: fetch suggestions
const fetchSuggestions = async (event) => { const fetchSuggestions = async (event) => {
@@ -136,12 +136,7 @@ export function LyricSearchInputField({ id, placeholder, setShowLyrics }) {
setLyricsResult(null); setLyricsResult(null);
setShowLyrics(false); setShowLyrics(false);
const toastId = toast.info("Searching...", { const toastId = toast.info("Searching...");
style: {
color: "#000",
backgroundColor: "rgba(217, 242, 255, 0.8)",
},
});
const startTime = Date.now(); const startTime = Date.now();
@@ -168,17 +163,17 @@ export function LyricSearchInputField({ id, placeholder, setShowLyrics }) {
setShowLyrics(true); setShowLyrics(true);
toast.update(toastId, { toast.update(toastId, {
type: "success",
render: `🦄 Found! (Took ${duration}s)`, render: `🦄 Found! (Took ${duration}s)`,
type: "", type: "",
style: { backgroundColor: "rgba(46, 186, 106, 1)" }, className: "Toastify__toast--success",
autoClose: 2000, autoClose: 2000,
hideProgressBar: true, hideProgressBar: true,
}); });
} catch (error) { } catch (error) {
toast.update(toastId, { toast.update(toastId, {
type: "error",
render: `😕 ${error.message}`, render: `😕 ${error.message}`,
type: "",
style: { backgroundColor: "rgba(255, 0, 0, 0.5)" },
autoClose: 5000, autoClose: 5000,
hideProgressBar: true, hideProgressBar: true,
}); });
@@ -241,14 +236,14 @@ export function LyricSearchInputField({ id, placeholder, setShowLyrics }) {
)} )}
{lyricsResult && ( {lyricsResult && (
<div className={`lyrics-card lyrics-card-${theme} mt-4 p-4 rounded-md shadow-md`}> <div className={`lyrics-card lyrics-card-${theme} mt-4 p-4 rounded-md shadow-md`}>
<div className="lyrics-content"> <div className="lyrics-content">
<div style={{ textAlign: "center", fontWeight: "bold", marginBottom: "1rem" }}> <div style={{ textAlign: "center", fontWeight: "bold", marginBottom: "1rem" }}>
{lyricsResult.artist} - {lyricsResult.song} {lyricsResult.artist} - {lyricsResult.song}
</div> </div>
<div dangerouslySetInnerHTML={{ __html: lyricsResult.lyrics }} /> <div dangerouslySetInnerHTML={{ __html: lyricsResult.lyrics }} />
</div> </div>
</div> </div>
)} )}
</div> </div>
); );
@@ -269,9 +264,7 @@ export const UICheckbox = forwardRef(function UICheckbox(props = {}, ref) {
if (checkedCount === 3) { if (checkedCount === 3) {
checkboxes.forEach(cb => cb.click()); checkboxes.forEach(cb => cb.click());
toast.error("All sources were excluded; exclusions have been reset.", { toast.error("All sources were excluded; exclusions have been reset.");
style: { backgroundColor: "rgba(255, 0, 0, 0.5)", color: "inherit" }
});
} }
}; };
@@ -300,7 +293,7 @@ export const UICheckbox = forwardRef(function UICheckbox(props = {}, ref) {
}); });
export function LyricResultBox(opts={}) { export function LyricResultBox(opts = {}) {
return ( return (
<div> <div>
<Box className={`lyrics-card lyrics-card-${theme}`} sx={{ p: 2 }}> <Box className={`lyrics-card lyrics-card-${theme}`} sx={{ p: 2 }}>

View File

@@ -2,7 +2,7 @@ import React from "react";
export default function BreadcrumbNav({ currentPage }) { export default function BreadcrumbNav({ currentPage }) {
const pages = [ const pages = [
{ key: "request", label: "Request Media", href: "." }, { key: "request", label: "Request Media", href: "../" },
{ key: "management", label: "Manage Requests", href: "requests" }, { key: "management", label: "Manage Requests", href: "requests" },
]; ];