app/panels/ObitsPanel.tsx (73 lines of code) (raw):

import React, { useEffect, useState } from "react"; import { ProjectsPanelProps, usePanelStyles } from "./PanelsCommon"; import PanelLauncher from "./PanelLauncher"; import clsx from "clsx"; import { Paper, Typography } from "@material-ui/core"; import { GetRecentObits } from "../services/PlutoCore"; import { useStyles as useCommonStyles } from "../CommonStyles"; interface ProjectSummary { title: string; id: number; owner: string; subject: string; } const ObitsPanel: React.FC<ProjectsPanelProps & { obitsToShow: number }> = ( props ) => { const classes = usePanelStyles(); const commonClasses = useCommonStyles(); const [recentObits, setRecentObits] = useState<ProjectSummary[]>([]); const jumpToObits = () => window.location.assign("/pluto-core/obituaries/"); const openProject = (projectId: number) => window.location.assign(`/pluto-core/project/${projectId}`); useEffect(() => { GetRecentObits(props.obitsToShow) .then((projects) => { const obits = projects.map((proj) => proj.isObitProject ? { title: proj.title, id: proj.id, owner: proj.user, subject: proj.isObitProject, } : undefined ); setRecentObits( obits.filter((o) => o !== undefined) as ProjectSummary[] ); }) .catch((err) => { console.error(`Could not load obituaries: ${err}`); }); }, [props.obitsToShow]); function toTitleCase(str: string) { return str.replace(/\w\S*/g, function (txt) { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); }); } return ( <> <Paper className={clsx(props.className, classes.panel)}> <PanelLauncher buttonLabel="Obituaries" caption="Find an obituary" onClick={jumpToObits} /> {recentObits.map((obit, k) => ( <PanelLauncher key={k} buttonLabel="Project page" caption={toTitleCase(obit.subject)} onClick={() => openProject(obit.id)} > <Typography className={commonClasses.secondaryPara} style={{ verticalAlign: "top", display: "inline" }} > {obit.title} created by {obit.owner} </Typography> </PanelLauncher> ))} </Paper> </> ); }; export default ObitsPanel;