Files
visiome.neuroinf.jp/src/database/blocks/Rankings.tsx
T
Yoshihiro OKUMURA 2b47d882f7 refactor: clear all biome lint diagnostics
Biome reported 229 diagnostics after aligning the config with
bsi-ni.brain.riken.jp. Fix them all so `biome check` passes clean
without per-rule overrides.

- replace `any` in LokiJS queries with an `ItemFilter` interface and
  a single `asLokiQuery()` cast, matching bsi-ni
- type the XOOPS redirect maps as
  `Record<string, { key: string; isNumber: boolean }>`
- use `ItemSubTypes<string>` instead of `any` for sub item types
- join author lists with `.join(', ')` instead of index-keyed nodes
- give list elements stable keys derived from their own data
- return `React.ReactNode` from `ListBase.renderBody()`
- drop the temporary `noArrayIndexKey` override from biome.json
2026-09-11 17:28:44 +09:00

135 lines
5.4 KiB
TypeScript

import { Fragment } from 'react';
import { Link } from 'react-router';
import type { MultiLang } from '../../config';
import Functions from '../../functions';
import { siteData } from '../../siteData';
import imageStar from '../assets/images/star.gif';
import ItemUtil, { type ItemCore } from '../lib/ItemUtil';
import styles from './Rankings.module.css';
interface Props {
lang: MultiLang;
}
const orderLabel = (order: number, lang: string) => {
return String(order) + (lang === 'en' ? Functions.ordinal(order) : '位');
};
const Rankings = (props: Props) => {
const items = [
{
title: Functions.mlang('[en]Frequently accessed items[/en][ja]頻繁に閲覧されるアイテム[/ja]', props.lang),
list: siteData().rankings.accessed.map((item, idx) => {
const url = ItemUtil.getUrl(item as ItemCore);
const title = Functions.mlang(item.title, props.lang);
const order = orderLabel(idx + 1, props.lang);
return (
<div key={url} className={styles.item}>
<div className={styles.order}>{order}</div>
<div className={styles.title}>
<Link to={url} title={title}>
{title}
</Link>
</div>
{idx === 0 && (
<div className={styles.star}>
<img src={imageStar} alt={order} />
</div>
)}
</div>
);
}),
},
{
title: Functions.mlang(
'[en]Frequently downloaded items[/en][ja]頻繁にダウンロードされるアイテム[/ja]',
props.lang
),
list: siteData().rankings.downloaded.map((item, idx) => {
const url = ItemUtil.getUrl(item as ItemCore);
const title = Functions.mlang(item.title, props.lang);
const order = orderLabel(idx + 1, props.lang);
return (
<div key={url} className={styles.item}>
<div className={styles.order}>{order}</div>
<div className={styles.title}>
<Link to={url} title={title}>
{title}
</Link>
</div>
{idx === 0 && (
<div className={styles.star}>
<img src={imageStar} alt={order} />
</div>
)}
</div>
);
}),
},
{
title: Functions.mlang(
'[en]Most active contributers[/en][ja]最も多くアイテムを公開したユーザ[/ja]',
props.lang
),
list: siteData().rankings.contributed.map((item, idx) => {
const name = item.name !== '' ? `${item.name} (${item.uname})` : item.uname;
const title = Functions.mlang(name, props.lang);
const order = orderLabel(idx + 1, props.lang);
return (
<div key={item.uname} className={styles.item}>
<div className={styles.order}>{order}</div>
<div className={styles.uname}>{title}</div>
<div className={styles.count}>({item.count})</div>
{idx === 0 && (
<div className={styles.star}>
<img src={imageStar} alt={order} />
</div>
)}
</div>
);
}),
},
{
title: Functions.mlang(
'[en]Frequently searched keywords[/en][ja]頻繁に検索されるキーワード[/ja]',
props.lang
),
list: siteData().rankings.searched.map((item, idx) => {
const url = ItemUtil.getSearchByKeywordUrl('all', item.keyword);
const title = `Search by: ${item.keyword}`;
const order = orderLabel(idx + 1, props.lang);
return (
<div key={url} className={styles.item}>
<div className={styles.order}>{order}</div>
<div className={styles.title}>
<Link to={url} title={title}>
{item.keyword}
</Link>
</div>
{idx === 0 && (
<div className={styles.star}>
<img src={imageStar} alt={order} />
</div>
)}
</div>
);
}),
},
];
return (
<div>
{items.map((item, idx) => {
return (
<Fragment key={item.title}>
{idx !== 0 && <hr />}
<h3 className={styles.heading}>{item.title}</h3>
<div>{item.list}</div>
</Fragment>
);
})}
</div>
);
};
export default Rankings;