Show Gregorian (عیسوی) years alongside Hijri for poets

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Anas Rashid 2026-10-08 20:53:53 +02:00
parent 74f3973191
commit 17200fc9aa
6 changed files with 17 additions and 10 deletions

View File

@ -31,11 +31,13 @@ for (const entry of manifest.Poets) {
try { try {
await client.query('BEGIN'); await client.query('BEGIN');
await client.query( await client.query(
`INSERT INTO poets (id, url, name, nickname, description, birth_year_ah, death_year_ah) `INSERT INTO poets (id, url, name, nickname, description, birth_year_ah, death_year_ah, birth_year_ce, death_year_ce)
VALUES ($1,$2,$3,$4,$5,$6,$7) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9)
ON CONFLICT (id) DO UPDATE SET url=$2, name=$3, nickname=$4, description=$5, birth_year_ah=$6, death_year_ah=$7`, ON CONFLICT (id) DO UPDATE SET url=$2, name=$3, nickname=$4, description=$5, birth_year_ah=$6, death_year_ah=$7,
birth_year_ce=$8, death_year_ce=$9`,
[poet.Id, poet.FullUrl, poet.Name, poet.Nickname, poet.Description, [poet.Id, poet.FullUrl, poet.Name, poet.Nickname, poet.Description,
poet.ValidBirthDate ? poet.BirthYearInLHijri : null, poet.ValidDeathDate ? poet.DeathYearInLHijri : null], poet.ValidBirthDate ? poet.BirthYearInLHijri : null, poet.ValidDeathDate ? poet.DeathYearInLHijri : null,
poet.BirthYearCE ?? null, poet.DeathYearCE ?? null],
); );
// categories depth-first so parents exist before children // categories depth-first so parents exist before children
const walk = async (url: string, position: number): Promise<void> => { const walk = async (url: string, position: number): Promise<void> => {

View File

@ -17,7 +17,7 @@ app.get('/health', async () => {
app.get('/api/poets', async () => { app.get('/api/poets', async () => {
const { rows } = await pool.query( const { rows } = await pool.query(
'SELECT id, url, name, nickname, birth_year_ah, death_year_ah, pin_order FROM poets ORDER BY birth_year_ah NULLS LAST, nickname', 'SELECT id, url, name, nickname, birth_year_ah, death_year_ah, birth_year_ce, death_year_ce, pin_order FROM poets ORDER BY birth_year_ah NULLS LAST, nickname',
); );
return rows; return rows;
}); });

View File

@ -15,6 +15,8 @@ CREATE TABLE IF NOT EXISTS poets (
pin_order integer -- featured on the home page (db/featured.sql) pin_order integer -- featured on the home page (db/featured.sql)
); );
ALTER TABLE poets ADD COLUMN IF NOT EXISTS pin_order integer; ALTER TABLE poets ADD COLUMN IF NOT EXISTS pin_order integer;
ALTER TABLE poets ADD COLUMN IF NOT EXISTS birth_year_ce integer; -- Gregorian (عیسوی)
ALTER TABLE poets ADD COLUMN IF NOT EXISTS death_year_ce integer;
CREATE TABLE IF NOT EXISTS categories ( CREATE TABLE IF NOT EXISTS categories (
id integer PRIMARY KEY, id integer PRIMARY KEY,

View File

@ -8,5 +8,8 @@ const ORDINALS = ['', 'پہلی', 'دوسری', 'تیسری', 'چوتھی', 'پ
export const centuryOf = (yearAh: number | null) => (yearAh ? Math.floor(yearAh / 100) + 1 : null); export const centuryOf = (yearAh: number | null) => (yearAh ? Math.floor(yearAh / 100) + 1 : null);
export const centuryName = (c: number | null) => (c ? `${ORDINALS[c] ?? ud(c)} صدی ہجری` : 'دیگر شعرا'); export const centuryName = (c: number | null) => (c ? `${ORDINALS[c] ?? ud(c)} صدی ہجری` : 'دیگر شعرا');
export const years = (birth: number | null, death: number | null) => const span = (a: number | null, b: number | null, mark: string) =>
birth || death ? `${birth ? ud(birth) : '؟'} – ${death ? ud(death) : '؟'} ھ` : ''; a || b ? `${a ? ud(a) : '؟'} – ${b ? ud(b) : '؟'} ${mark}` : '';
// Hijri and Gregorian (عیسوی): "۱۲۹۴ – ۱۳۵۷ ھ · ۱۸۷۷ – ۱۹۳۸ ء"
export const years = (p: { birth_year_ah: number | null; death_year_ah: number | null; birth_year_ce?: number | null; death_year_ce?: number | null }) =>
[span(p.birth_year_ah, p.death_year_ah, 'ھ'), span(p.birth_year_ce ?? null, p.death_year_ce ?? null, 'ء')].filter(Boolean).join(' · ');

View File

@ -34,7 +34,7 @@ const title = page.type === 'poem' ? page.poem.title : page.type === 'poet' ? pa
{page.type === 'poet' && ( {page.type === 'poet' && (
<> <>
<h1>{page.poet.name}</h1> <h1>{page.poet.name}</h1>
<p class="muted">{years(page.poet.birth_year_ah, page.poet.death_year_ah)}</p> <p class="muted">{years(page.poet)}</p>
{page.poet.description && <div class="intro">{page.poet.description}</div>} {page.poet.description && <div class="intro">{page.poet.description}</div>}
</> </>
)} )}

View File

@ -29,7 +29,7 @@ const pinned = poets.filter((p) => p.pin_order).sort((a, b) => a.pin_order! - b.
<h2>مقبول شعرا</h2> <h2>مقبول شعرا</h2>
<div class="poets"> <div class="poets">
{pinned.map((p) => ( {pinned.map((p) => (
<a class="poet-card" href={p.url}>{p.nickname}<small>{years(p.birth_year_ah, p.death_year_ah)}</small></a> <a class="poet-card" href={p.url}>{p.nickname}<small>{years(p)}</small></a>
))} ))}
</div> </div>
</section> </section>
@ -42,7 +42,7 @@ const pinned = poets.filter((p) => p.pin_order).sort((a, b) => a.pin_order! - b.
{list.map((p) => ( {list.map((p) => (
<a class="poet-card" href={p.url}> <a class="poet-card" href={p.url}>
{p.nickname} {p.nickname}
<small>{years(p.birth_year_ah, p.death_year_ah)}</small> <small>{years(p)}</small>
</a> </a>
))} ))}
</div> </div>