URL handling both on navigation and when directly calling URL.
directly calling only works for Article ID
This commit is contained in:
@@ -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> = {
|
||||
|
||||
@@ -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" });
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user