Rebuild the site on the stack the other converted sites share: Vite 8, React 19, TypeScript 7, react-router 8, Biome and sanitize.css, with the site data moved out of the bundle into static-contents/. - base the database and forum code on cerebellum.neuroinf.jp, keeping the CBSN item fields for papers, books and presentations - serve the XooNIps and forum data from modules/, redirecting the old download and /database/file URLs - restate the theme sizes as border-box totals and keep form controls on white - track page views with GA4
65 lines
2.0 KiB
TypeScript
65 lines
2.0 KiB
TypeScript
import { Helmet } from '@dr.pogodin/react-helmet';
|
|
import { useEffect, useState } from 'react';
|
|
import { useParams } from 'react-router';
|
|
import Loading from '../common/lib/Loading';
|
|
import PageNotFound from '../common/lib/PageNotFound';
|
|
import type { MultiLang } from '../config';
|
|
import Functions from '../functions';
|
|
import ItemType from './item-type';
|
|
import ItemUtil, { type Item } from './lib/ItemUtil';
|
|
|
|
interface Props {
|
|
lang: MultiLang;
|
|
}
|
|
|
|
const DatabaseDetailItem = (props: Props) => {
|
|
const { lang } = props;
|
|
const params = useParams<{ id?: string; doi?: string }>();
|
|
const id = typeof params.id !== 'undefined' ? (params.id.match(/^\d+$/) !== null ? parseInt(params.id, 10) : 0) : 0;
|
|
const doi = params.doi ?? '';
|
|
const [loading, setLoading] = useState(true);
|
|
const [item, setItem] = useState<Item | null>(null);
|
|
|
|
useEffect(() => {
|
|
let active = true;
|
|
const receive = (found: Item | null) => {
|
|
if (active) {
|
|
setItem(found);
|
|
setLoading(false);
|
|
}
|
|
};
|
|
if (doi !== '') {
|
|
ItemUtil.getByDoi(doi, receive);
|
|
} else if (id !== 0) {
|
|
ItemUtil.get(id, receive);
|
|
} else {
|
|
receive(null);
|
|
}
|
|
return () => {
|
|
active = false;
|
|
};
|
|
}, [id, doi]);
|
|
|
|
if (loading) {
|
|
return <Loading />;
|
|
}
|
|
if (item === null) {
|
|
return <PageNotFound lang={lang} />;
|
|
}
|
|
return (
|
|
<>
|
|
<Helmet>
|
|
<title>
|
|
{Functions.mlang(item.title, lang)} -{' '}
|
|
{Functions.mlang('[en]Database[/en][ja]データベース[/ja]', lang)} - {Functions.siteTitle(lang)}
|
|
</title>
|
|
</Helmet>
|
|
<h3>{Functions.mlang('[en]Item Detail[/en][ja]アイテム詳細[/ja]', lang)}</h3>
|
|
<br />
|
|
<ItemType.Detail lang={lang} item={item} />
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default DatabaseDetailItem;
|