cleaner view for Blog

This commit is contained in:
2025-11-18 16:05:27 +05:30
parent 383b424bdf
commit 87bdafb6a3
2 changed files with 46 additions and 108 deletions

View File

@@ -21,136 +21,74 @@ export default function Blog(props: { disableCustomTheme?: boolean }) {
const { articles, loading, error } = useArticles(); const { articles, loading, error } = useArticles();
const { currentUser } = useAuth(); const { currentUser } = useAuth();
const [selectedArticle, setSelectedArticle] = React.useState<number | null>(null); const [ui, setUI] = React.useState({
const [showLogin, setShowLogin] = React.useState(false); selectedArticle: null as number | null,
const [showRegister, setShowRegister] = React.useState(false); view: "home" as View,
const [showProfile, setShowProfile] = React.useState(false); });
const [showEditor, setShowEditor] = React.useState(false); const show = (view: View) => {
setUI(prev => ({ ...prev, view }));
window.scrollTo({ top: 0, behavior: "smooth" });
};
const openLogin = () => show("login");
const openRegister = () => show("register");
const openProfile = () => show("profile");
const openEditor = () => show("editor");
const handleSelectArticle = (index: number) => { const openArticle = (index: number) => {
setSelectedArticle(index); setUI({ selectedArticle: index, view: "article" });
window.scrollTo({ top: 0, behavior: 'smooth' }); window.scrollTo({ top: 0, behavior: "smooth" });
};
const handleShowLogin = () => {
setShowLogin(true);
setShowRegister(false);
window.scrollTo({ top: 0, behavior: 'smooth' });
};
const handleShowRegister = () => {
setShowRegister(true);
setShowLogin(false);
window.scrollTo({ top: 0, behavior: 'smooth' });
};
const handleHideAuth = () => {
setShowLogin(false);
setShowRegister(false);
};
const handleShowProfile = () => {
setShowProfile(true);
window.scrollTo({ top: 0, behavior: 'smooth' });
};
const handleHideProfile = () => {
setShowProfile(false);
};
const handleShowEditor = () => {
setShowEditor(true);
};
const handleHideEditor = () => {
setShowEditor(false);
};
const handleArticleViewBack = () => setSelectedArticle(null);
const handleArticleEditorBack = () => {
handleHideEditor()
window.scrollTo({ top: 0, behavior: 'smooth' });
}; };
// derive a single source of truth for view const goHome = () => setUI({ selectedArticle: null, view: "home" });
const view: View = React.useMemo(() => {
if (selectedArticle !== null && !showEditor) return 'article';
if (showRegister) return 'register';
if (showLogin) return 'login';
if (showProfile) return 'profile';
if (showEditor) return 'editor';
return 'home';
}, [selectedArticle, showLogin, showRegister, showProfile, showEditor]);
// render function keeps JSX tidy
const renderView = () => { const renderView = () => {
switch (view) { switch (ui.view) {
case 'register': case "login":
return <Register onBack={handleHideAuth} />; return <Login onBack={goHome} onRegister={openRegister} />;
case 'login':
case "register":
return <Register onBack={goHome} />;
case "profile":
return <Profile onBack={goHome} />;
case "article":
return ( return (
<Login <ArticleView
onBack={handleHideAuth} article={articles[ui.selectedArticle!]}
onRegister={() => { onBack={goHome}
handleShowRegister(); onEdit={openEditor}
}}
/> />
); );
case 'profile':
case "editor":
return ( return (
<Profile <ArticleEditor
onBack={handleHideProfile} article={ui.selectedArticle !== null ? articles[ui.selectedArticle] : null}
onBack={goHome}
/> />
); );
case 'article':
if (selectedArticle == null || !articles[selectedArticle]) return null;
return <ArticleView
article={articles[selectedArticle]}
onBack={handleArticleViewBack}
onEdit={handleShowEditor}
/>;
case 'editor':
if (selectedArticle == null || !articles[selectedArticle])
return <ArticleEditor
onBack={handleArticleEditorBack}
/>
return <ArticleEditor
article={articles[selectedArticle] || null}
onBack={handleArticleEditorBack}
/>
case 'home':
default: default:
return ( return (
<> <>
<Box sx={{ display: 'flex', justifyContent: 'flex-end', mb: 2, gap: 1 }}> <Box sx={{ display: "flex", justifyContent: "flex-end", mb: 2, gap: 1 }}>
{!currentUser ? ( {!currentUser ? (
<> <Button variant="outlined" onClick={openLogin}>Login</Button>
<Button
variant="outlined"
color="primary"
onClick={handleShowLogin}
>
Login
</Button>
</>
) : ( ) : (
<> <>
<Button <Button variant="outlined" onClick={openProfile}>
variant="outlined"
color="primary"
onClick={handleShowProfile}
>
{currentUser.username} {currentUser.username}
</Button> </Button>
<Button <Button variant="contained" onClick={openEditor}>
variant="contained"
color="primary"
onClick={handleShowEditor}
>
New Article New Article
</Button> </Button>
</> </>
)} )}
</Box> </Box>
<MainContent articles={articles} onSelectArticle={handleSelectArticle} /> <MainContent articles={articles} onSelectArticle={openArticle} />
<Latest <Latest articles={articles} onSelectArticle={openArticle} />
articles={articles}
onSelectArticle={handleSelectArticle}
onLoadMore={async () => {}}
/>
</> </>
); );
} }
@@ -210,13 +148,13 @@ export default function Blog(props: { disableCustomTheme?: boolean }) {
flexDirection: 'column', flexDirection: 'column',
my: 4, my: 4,
gap: 4, gap: 4,
pb: view === 'home' ? 24 : 0, pb: ui.view === 'home' ? 24 : 0,
}} }}
> >
{renderView()} {renderView()}
</Container> </Container>
{view === 'home' && ( {ui.view === 'home' && (
<Box <Box
component="footer" component="footer"
sx={{ sx={{

View File

@@ -13,7 +13,7 @@ export interface ArticleProps {
} }
export interface ArticleEditorProps { export interface ArticleEditorProps {
article?: ArticleModel; article?: ArticleModel | null;
onBack: () => void; onBack: () => void;
} }