(props)
| 26 | }; |
| 27 | |
| 28 | export default function BlogPage(props) { |
| 29 | const VITE_SERVER_PORT = import.meta.env.VITE_SERVER_PORT || "https://bitbox-uxbo.onrender.com"; |
| 30 | |
| 31 | const [searchTerm, setSearchTerm] = useState(""); |
| 32 | const [selectedCategory, setSelectedCategory] = useState("All"); |
| 33 | const [blogPosts, setBlogPosts] = useState([]); |
| 34 | const [isPaused, setIsPaused] = useState(false); |
| 35 | const [currentPosition, setCurrentPosition] = useState(0); |
| 36 | const [isPlaying, setIsPlaying] = useState(false); |
| 37 | const speechInstanceRef = useRef(null); |
| 38 | |
| 39 | const categories = ["All", ...new Set(blogPosts.map((post) => post.category))]; |
| 40 | |
| 41 | const filteredPosts = blogPosts.filter((post) => { |
| 42 | const matchesSearch = |
| 43 | post.title.toLowerCase().includes(searchTerm.toLowerCase()) || |
| 44 | post.content.toLowerCase().includes(searchTerm.toLowerCase()); |
| 45 | const matchesCategory = |
| 46 | selectedCategory === "All" || post.category === selectedCategory; |
| 47 | return matchesSearch && matchesCategory; |
| 48 | }); |
| 49 | |
| 50 | // const formatDate = (dateString) => { |
| 51 | // const date = new Date(dateString); |
| 52 | // if (isNaN(date.getTime())) { |
| 53 | // throw new Error("Invalid date format"); |
| 54 | // } |
| 55 | // const day = String(date.getDate()).padStart(2, "0"); |
| 56 | // const month = String(date.getMonth() + 1).padStart(2, "0"); |
| 57 | // const year = date.getFullYear(); |
| 58 | // return `${day}-${month}-${year}`; |
| 59 | // }; |
| 60 | |
| 61 | const categoryImage = (cat) => { |
| 62 | const imgSrc = images.find((image) => image.category === cat); |
| 63 | return imgSrc ? imgSrc.src : ""; |
| 64 | }; |
| 65 | |
| 66 | const fetchData = async () => { |
| 67 | try { |
| 68 | let response = await fetch(`${VITE_SERVER_PORT}/api/blog/all-blog`); |
| 69 | let data = await response.json(); |
| 70 | setBlogPosts(data.blogs); |
| 71 | console.log(data.blogs); |
| 72 | } catch (error) { |
| 73 | console.error(error); |
| 74 | } |
| 75 | }; |
| 76 | |
| 77 | const handlePlay = (id, title, excerpt) => { |
| 78 | const textToSpeak = `${title}. ${excerpt}`; |
| 79 | document.getElementsByClassName(`pause-button-${id}`)[0].classList.remove('hidden') |
| 80 | document.getElementsByClassName(`speak-button-${id}`)[0].classList.add('hidden') |
| 81 | console.log(textToSpeak) |
| 82 | if (isPaused && speechInstanceRef.current) { |
| 83 | setIsPaused(true); |
| 84 | window.speechSynthesis.speak(speechInstanceRef.current); |
| 85 | } else { |
nothing calls this directly
no test coverage detected