URL handling both on navigation and when directly calling URL.

directly calling only works for Article ID
This commit is contained in:
2025-11-20 16:58:32 +05:30
parent 2b578fd12e
commit 7bdf84b6aa
2 changed files with 70 additions and 8 deletions

View File

@@ -1,4 +1,5 @@
import * as React from 'react';
import { useEffect } from 'react';
import CssBaseline from '@mui/material/CssBaseline';
import Container from '@mui/material/Container';
import Box from '@mui/material/Box';
@@ -15,10 +16,17 @@ import Profile from './components/Profile';
import { useArticles } from './providers/Article';
import { useAuth } from './providers/Author';
import { View, useViewRouter } from "./types/views";
import { ArticlesModel } from "./types/models";
import { ArticleModel, ArticlesModel } from "./types/models";
import { ArticleViewProps, ArticleEditorProps } from "./types/props";
function HomeView({ currentUser, open_login, open_profile, open_create, articles, openArticle }: any) {
function HomeView({
currentUser,
open_login,
open_profile,
open_create,
articles,
openArticle
}: any) {
return (
<>
<Box sx={{ display: "flex", justifyContent: "flex-end", mb: 2, gap: 1 }}>
@@ -47,10 +55,29 @@ export default function Blog(props: { disableCustomTheme?: boolean }) {
const { currentUser } = useAuth();
const [ui, setUI] = React.useState({
selectedArticle: null as number | null,
selectedArticle: null as ArticleModel | null,
view: "home" as View,
});
useEffect(() => {
if (loading) return;
const path = window.location.pathname;
const parts = path.split('/').filter(Boolean);
if (parts[0] === 'articles' && parts[1]) {
const id = parts[1];
const article = articles.readById(id);
if (article) {
setUI({
selectedArticle: article,
view: 'article',
});
}
}
}, [loading]);
const {
goBack,
navigateToChildren,
@@ -61,7 +88,7 @@ export default function Blog(props: { disableCustomTheme?: boolean }) {
ui: any;
articles: ArticlesModel;
currentUser: any;
openArticle: (index: number) => void;
openArticle: (article: ArticleModel) => void;
};
type ViewComponentEntry<P> = {

View File

@@ -1,3 +1,5 @@
import {ArticleModel} from "./models";
export type View =
| "home"
| "login"
@@ -39,9 +41,31 @@ export const VIEW_TREE: Record<View, ViewNode> = {
},
};
export const VIEW_URL: Record<View, (ui?: any) => string> = {
home: () => "/",
login: () => "/login",
register: () => "/register",
profile: () => "/profile",
create: () => "/create",
article: (ui) => `/articles/${ui.selectedArticle._id ?? ""}`,
editor: (ui) => `/articles/${ui.selectedArticle._id ?? ""}/edit`,
};
export function useViewRouter(setUI: any) {
const navigate = (view: View) => {
setUI((prev: any) => ({ ...prev, view }));
const navigate = (
view: View,
nextState?: any
) => {
setUI((prev: any) => {
const newState = { ...prev, ...nextState, view };
// update URL
const url = VIEW_URL[view](newState);
window.history.pushState(newState, "", url);
return newState;
});
window.scrollTo({ top: 0, behavior: "smooth" });
};
@@ -51,8 +75,19 @@ export function useViewRouter(setUI: any) {
if (parent) navigate(parent);
};
const openArticle = (i: number) => {
setUI({ selectedArticle: i, view: "article" });
const openArticle = (article: ArticleModel) => {
setUI((prev: any) => {
const newState = {
...prev,
selectedArticle: article,
view: "article",
};
const url = `/articles/${article._id}`;
window.history.pushState(newState, "", url);
return newState;
});
window.scrollTo({ top: 0, behavior: "smooth" });
};