REFACTOR: Implement full page reloads for state-critical navigation
This commit is contained in:
@@ -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"
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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 (
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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.");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user