REFACTOR: Implement full page reloads for state-critical navigation

This commit is contained in:
Chris-1010
2025-02-22 13:00:20 +00:00
parent aa1b85513f
commit 12d9f3660a
9 changed files with 35 additions and 42 deletions

View File

@@ -1,7 +1,6 @@
import React, { useState } from "react"; import React, { useState } from "react";
import Input from "../Input/Input"; import Input from "../Input/Input";
import Button from "../Input/Button"; import Button from "../Input/Button";
import { useAuth } from "../../context/AuthContext";
interface ResetPasswordData { interface ResetPasswordData {
newPassword: string; newPassword: string;
@@ -14,7 +13,7 @@ interface ResetPasswordErrors {
} }
interface SubmitProps { interface SubmitProps {
onSubmit: () => void; onSubmit: (success: boolean) => void;
token: string; token: string;
} }
@@ -56,7 +55,6 @@ const PasswordResetForm: React.FC<SubmitProps> = ({ onSubmit, token }) => {
const handleSubmit = async (e: React.FormEvent) => { const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault(); e.preventDefault();
onSubmit();
if (validateResetForm()) { if (validateResetForm()) {
try { try {
@@ -74,6 +72,7 @@ const PasswordResetForm: React.FC<SubmitProps> = ({ onSubmit, token }) => {
if (!response.ok) { if (!response.ok) {
const data = await response.json(); const data = await response.json();
onSubmit(false);
throw new Error( throw new Error(
data.error || "An error has occurred while resetting" data.error || "An error has occurred while resetting"
); );

View File

@@ -1,5 +1,4 @@
import React from "react"; import React from "react";
import { Link } from "react-router-dom";
interface LogoProps { interface LogoProps {
variant?: "home" | "default"; variant?: "home" | "default";
@@ -8,24 +7,25 @@ interface LogoProps {
const Logo: React.FC<LogoProps> = ({ variant = "default" }) => { const Logo: React.FC<LogoProps> = ({ variant = "default" }) => {
const gradient = "text-transparent group-hover:mx-1 transition-all"; const gradient = "text-transparent group-hover:mx-1 transition-all";
return ( return (
<Link to="/" className="cursor-pointer"> <div
<div id="logo"
id="logo" className={`group py-3 cursor-pointer text-center font-bold hover:scale-110 transition-all ${
className={`group py-3 text-center font-bold hover:scale-110 transition-all ${variant === "home" ? "text-[12vh]" : "text-[4vh]"}`} variant === "home" ? "text-[12vh]" : "text-[4vh]"
> }`}
<h6 className="text-sm bg-gradient-to-br from-blue-400 via-green-500 to-indigo-500 font-black text-transparent bg-clip-text"> onClick={() => {window.location.href = "/";}}
Go on, have a... >
</h6> <h6 className="text-sm bg-gradient-to-br from-blue-400 via-green-500 to-indigo-500 font-black text-transparent bg-clip-text">
<div className="flex w-fit min-w-[30vw] bg-logo bg-clip-text animate-moving_text_colour bg-[length:300%_300%] justify-center leading-none transition-all"> Go on, have a...
<span className={gradient}>G</span> </h6>
<span className={gradient}>A</span> <div className="flex w-fit min-w-[30vw] bg-logo bg-clip-text animate-moving_text_colour bg-[length:300%_300%] justify-center leading-none transition-all">
<span className={gradient}>N</span> <span className={gradient}>G</span>
<span className={gradient}>D</span> <span className={gradient}>A</span>
<span className={gradient}>E</span> <span className={gradient}>N</span>
<span className={gradient}>R</span> <span className={gradient}>D</span>
</div> <span className={gradient}>E</span>
<span className={gradient}>R</span>
</div> </div>
</Link> </div>
); );
}; };

View File

@@ -16,7 +16,6 @@ import { useAuth } from "../../context/AuthContext";
import QuickSettings from "../Settings/QuickSettings"; import QuickSettings from "../Settings/QuickSettings";
import { useSidebar } from "../../context/SidebarContext"; import { useSidebar } from "../../context/SidebarContext";
import { useQuickSettings } from "../../context/QuickSettingsContext"; import { useQuickSettings } from "../../context/QuickSettingsContext";
import { useNavigate } from "react-router-dom";
interface NavbarProps { interface NavbarProps {
variant?: "home" | "default"; variant?: "home" | "default";
@@ -27,7 +26,6 @@ const Navbar: React.FC<NavbarProps> = ({ variant = "default" }) => {
const { showAuthModal, setShowAuthModal } = useAuthModal(); const { showAuthModal, setShowAuthModal } = useAuthModal();
const { showSideBar, setShowSideBar } = useSidebar(); const { showSideBar, setShowSideBar } = useSidebar();
const { showQuickSettings, setShowQuickSettings } = useQuickSettings(); const { showQuickSettings, setShowQuickSettings } = useQuickSettings();
const navigate = useNavigate();
const handleLogout = () => { const handleLogout = () => {
console.log("Logging out..."); console.log("Logging out...");
@@ -152,7 +150,7 @@ const Navbar: React.FC<NavbarProps> = ({ variant = "default" }) => {
extraClasses={`${ extraClasses={`${
variant === "home" ? "absolute top-[2vh] right-[10vw]" : "" variant === "home" ? "absolute top-[2vh] right-[10vw]" : ""
} flex flex-row items-center`} } flex flex-row items-center`}
onClick={() => navigate("/go-live")} onClick={() => window.location.href = "/go-live"}
> >
<LiveIcon className="h-15 w-15 mr-2" /> <LiveIcon className="h-15 w-15 mr-2" />
Go Live Go Live

View File

@@ -5,7 +5,6 @@ import AuthModal from "../Auth/AuthModal";
import { useAuthModal } from "../../hooks/useAuthModal"; import { useAuthModal } from "../../hooks/useAuthModal";
import { useAuth } from "../../context/AuthContext"; import { useAuth } from "../../context/AuthContext";
import { useSocket } from "../../context/SocketContext"; import { useSocket } from "../../context/SocketContext";
import { useNavigate } from "react-router-dom";
interface ChatMessage { interface ChatMessage {
chatter_username: string; chatter_username: string;
@@ -28,7 +27,6 @@ const ChatPanel: React.FC<ChatPanelProps> = ({
const [messages, setMessages] = useState<ChatMessage[]>([]); const [messages, setMessages] = useState<ChatMessage[]>([]);
const [inputMessage, setInputMessage] = useState(""); const [inputMessage, setInputMessage] = useState("");
const chatContainerRef = useRef<HTMLDivElement>(null); const chatContainerRef = useRef<HTMLDivElement>(null);
const navigate = useNavigate();
// Join chat room when component mounts // Join chat room when component mounts
useEffect(() => { useEffect(() => {
@@ -147,7 +145,7 @@ const ChatPanel: React.FC<ChatPanelProps> = ({
onClick={() => onClick={() =>
msg.chatter_username === username msg.chatter_username === username
? null ? null
: navigate(`/user/${msg.chatter_username}`) : window.location.href = `/user/${msg.chatter_username}`
} }
> >
<img <img
@@ -170,7 +168,7 @@ const ChatPanel: React.FC<ChatPanelProps> = ({
onClick={() => onClick={() =>
msg.chatter_username === username msg.chatter_username === username
? null ? null
: navigate(`/user/${msg.chatter_username}`) : window.location.href = `/user/${msg.chatter_username}`
} }
> >
{msg.chatter_username} {msg.chatter_username}

View File

@@ -1,7 +1,6 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import ListRow from "../components/Layout/ListRow"; import ListRow from "../components/Layout/ListRow";
import { useNavigate } from "react-router-dom";
import DynamicPageContent from "../components/Layout/DynamicPageContent"; import DynamicPageContent from "../components/Layout/DynamicPageContent";
interface StreamData { interface StreamData {
@@ -18,7 +17,6 @@ const CategoryPage: React.FC = () => {
const { category_name } = useParams<{ category_name: string }>(); const { category_name } = useParams<{ category_name: string }>();
const [streams, setStreams] = useState<StreamData[]>([]); const [streams, setStreams] = useState<StreamData[]>([]);
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const navigate = useNavigate();
useEffect(() => { useEffect(() => {
const fetchCategoryStreams = async () => { const fetchCategoryStreams = async () => {
@@ -54,7 +52,7 @@ const CategoryPage: React.FC = () => {
}, [category_name]); }, [category_name]);
const handleStreamClick = (streamerName: string) => { const handleStreamClick = (streamerName: string) => {
navigate(`/${streamerName}`); window.location.href = `/${streamerName}`;
}; };
if (isLoading) { if (isLoading) {

View File

@@ -15,11 +15,11 @@ const HomePage: React.FC<HomePageProps> = ({ variant = "default" }) => {
const navigate = useNavigate(); const navigate = useNavigate();
const handleStreamClick = (streamerName: string) => { const handleStreamClick = (streamerName: string) => {
navigate(`/${streamerName}`); window.location.href = `/${streamerName}`;
}; };
const handleCategoryClick = (categoryName: string) => { const handleCategoryClick = (categoryName: string) => {
navigate(`category/${categoryName}`); navigate(`/category/${categoryName}`);
}; };
return ( return (

View File

@@ -1,11 +1,9 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import Button from "../components/Input/Button"; import Button from "../components/Input/Button";
// @ts-ignore // @ts-ignore
import ChromeDinoGame from "react-chrome-dino"; import ChromeDinoGame from "react-chrome-dino";
const NotFoundPage: React.FC = () => { const NotFoundPage: React.FC = () => {
const navigate = useNavigate();
const [stars, setStars] = useState<{ x: number; y: number }[]>([]); const [stars, setStars] = useState<{ x: number; y: number }[]>([]);
const starSize = 20; const starSize = 20;
@@ -59,7 +57,7 @@ const NotFoundPage: React.FC = () => {
<h1 className="text-6xl font-bold mb-4">404</h1> <h1 className="text-6xl font-bold mb-4">404</h1>
<p className="text-2xl mb-8">Page Not Found</p> <p className="text-2xl mb-8">Page Not Found</p>
<ChromeDinoGame /> <ChromeDinoGame />
<Button extraClasses="z-[100]" onClick={() => navigate("/")}> <Button extraClasses="z-[100]" onClick={() => window.location.href = "/"}>
Go Home Go Home
</Button> </Button>
</div> </div>

View File

@@ -1,15 +1,17 @@
import React from "react"; import React from "react";
import PasswordResetForm from "../components/Auth/PasswordResetForm"; import PasswordResetForm from "../components/Auth/PasswordResetForm";
import { useParams, useNavigate } from "react-router-dom"; import { useParams } from "react-router-dom";
const ResetPasswordPage: React.FC = () => { const ResetPasswordPage: React.FC = () => {
const { token } = useParams<{ token: string }>(); const { token } = useParams<{ token: string }>();
const navigate = useNavigate();
const handlePasswordReset = (success: boolean) => { const handlePasswordReset = (success: boolean) => {
if (success) { if (success) {
alert("Password reset successful!"); alert("Password reset successful!");
navigate("/"); window.location.href = "/";
}
else {
alert("Password reset failed.");
} }
}; };

View File

@@ -48,7 +48,7 @@ const ResultsPage: React.FC = ({}) => {
<li <li
key={index} key={index}
className="border p-2 rounded my-2 cursor-pointer" className="border p-2 rounded my-2 cursor-pointer"
onClick={() => navigate(`/user/${user.username}`)} onClick={() => window.location.href = `/user/${user.username}`}
> >
{user.is_live ? "🔴" : ""} {user.username} {user.is_live ? "🔴" : ""} {user.username}
</li> </li>
@@ -63,7 +63,7 @@ const ResultsPage: React.FC = ({}) => {
<li <li
key={index} key={index}
className="border p-2 rounded my-2 cursor-pointer" className="border p-2 rounded my-2 cursor-pointer"
onClick={() => navigate(`/${stream.username}`)} onClick={() => window.location.href = `/${stream.username}`}
> >
{stream.title} - {stream.username} - {stream.num_viewers} viewers {stream.title} - {stream.username} - {stream.num_viewers} viewers
</li> </li>