Skip to content

Commit 734fd27

Browse files
committed
feat: add contribution and contributor page rendering logic
1 parent 644b109 commit 734fd27

5 files changed

Lines changed: 110 additions & 18 deletions

File tree

web-server/src/app/index.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import express from "express";
2+
import { renderContributionPage } from "src/handler/contribution";
3+
import { renderContributorPage } from "src/handler/contributor";
24
import { renderProjectPage } from "src/handler/project";
35
import { generateContributionsSitemap } from "src/handler/sitemap/contributions";
46
import { generateContributorsSitemap } from "src/handler/sitemap/contributors";
@@ -35,23 +37,17 @@ app.get(/^\/(?:([a-z]{2})\/)?projects\/(.*)$/, (req, res) => {
3537
});
3638

3739
app.get(/^\/(?:([a-z]{2})\/)?contribute\/(.*)$/, (req, res) => {
38-
const lang = req.params[0] || "en";
39-
const contributionId = req.params[1];
40+
const lang = validateLangOrDefault(req.params[0]);
41+
const contributionId = req.params[1].split("-").slice(-2).join("-");
4042

41-
res.json({
42-
lang,
43-
contributionId,
44-
});
43+
renderContributionPage(res, lang, contributionId);
4544
});
4645

4746
app.get(/^\/(?:([a-z]{2})\/)?team\/(.*)$/, (req, res) => {
48-
const lang = req.params[0] || "en";
47+
const lang = validateLangOrDefault(req.params[0]);
4948
const contributorId = req.params[1];
5049

51-
res.json({
52-
lang,
53-
teamId: contributorId,
54-
});
50+
renderContributorPage(res, lang, contributorId);
5551
});
5652

5753
app.use(express.static(staticPath));
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Language } from "@dzcode.io/models/dist/language";
2+
import { Response } from "express";
3+
import { plainLocalize } from "@dzcode.io/web/dist/components/locale/utils";
4+
import { dictionary, AllDictionaryKeys } from "@dzcode.io/web/dist/components/locale/dictionary";
5+
import { fetchV2Factory } from "@dzcode.io/utils/dist/fetch/factory";
6+
import { Endpoints } from "@dzcode.io/api/dist/app/endpoints";
7+
import { fullstackConfig } from "src/utils/config";
8+
import { getContributionURL } from "@dzcode.io/web/dist/utils/contribution";
9+
import { templateContent } from "./templates";
10+
import { notFoundPath } from "src/utils/paths";
11+
12+
export const renderContributionPage = async (
13+
res: Response,
14+
lang: Language,
15+
contributionId: string,
16+
) => {
17+
const localize = (key: AllDictionaryKeys) =>
18+
plainLocalize(dictionary, lang.code, key, "NO-TRANSLATION");
19+
const fetchV2 = fetchV2Factory<Endpoints>(fullstackConfig, lang.code);
20+
21+
try {
22+
const { contribution } = await fetchV2("api:contributions/:id/title", {
23+
params: { id: contributionId },
24+
});
25+
const pageTitle = `${localize("contribution-title-pre")} ${contribution.title} ${localize("contribution-title-post")}`;
26+
27+
const newData = templateContent
28+
.replace(/{{template-title}}/g, pageTitle)
29+
.replace(/{{template-description}}/g, localize("contribute-description"))
30+
.replace(/{{template-lang}}/g, lang.code)
31+
.replace(
32+
/{{template-canonical}}/g,
33+
getContributionURL({ id: contributionId, title: contribution.title }, lang),
34+
);
35+
36+
res.setHeader("Content-Type", "text/html; charset=utf-8");
37+
res.status(200).send(newData);
38+
} catch (error) {
39+
// @TODO-ZM: log error to loki
40+
console.error(error);
41+
res.status(404).sendFile(notFoundPath);
42+
}
43+
};
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { Language } from "@dzcode.io/models/dist/language";
2+
import { Response } from "express";
3+
import { plainLocalize } from "@dzcode.io/web/dist/components/locale/utils";
4+
import { dictionary, AllDictionaryKeys } from "@dzcode.io/web/dist/components/locale/dictionary";
5+
import { fetchV2Factory } from "@dzcode.io/utils/dist/fetch/factory";
6+
import { Endpoints } from "@dzcode.io/api/dist/app/endpoints";
7+
import { fullstackConfig } from "src/utils/config";
8+
import { getContributorURL } from "@dzcode.io/web/dist/utils/contributor";
9+
import { templateContent } from "./templates";
10+
import { notFoundPath } from "src/utils/paths";
11+
12+
export const renderContributorPage = async (
13+
res: Response,
14+
lang: Language,
15+
contributorId: string,
16+
) => {
17+
const localize = (key: AllDictionaryKeys) =>
18+
plainLocalize(dictionary, lang.code, key, "NO-TRANSLATION");
19+
const fetchV2 = fetchV2Factory<Endpoints>(fullstackConfig, lang.code);
20+
21+
try {
22+
const { contributor } = await fetchV2("api:contributors/:id/name", {
23+
params: { id: contributorId },
24+
});
25+
const pageTitle = `${localize("contributor-title-pre")} ${contributor.name} ${localize("contributor-title-post")}`;
26+
27+
const newData = templateContent
28+
.replace(/{{template-title}}/g, pageTitle)
29+
.replace(/{{template-description}}/g, localize("team-description"))
30+
.replace(/{{template-lang}}/g, lang.code)
31+
.replace(/{{template-canonical}}/g, getContributorURL({ id: contributorId }, lang));
32+
33+
res.setHeader("Content-Type", "text/html; charset=utf-8");
34+
res.status(200).send(newData);
35+
} catch (error) {
36+
// @TODO-ZM: log error to loki
37+
console.error(error);
38+
res.status(404).sendFile(notFoundPath);
39+
}
40+
};

web/src/utils/contribution.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
import { ContributionNoLang } from "@dzcode.io/models/dist/contribution";
2+
import { DEFAULT_LANGUAGE, Language } from "@dzcode.io/models/dist/language";
23

3-
export function getContributionURL({
4-
id,
5-
title,
6-
}: Pick<ContributionNoLang, "id" | "title">): string {
7-
return `/contribute/${title.replace(/\s/g, "-")}-${id}`;
4+
export function getContributionURL(
5+
{ id, title }: Pick<ContributionNoLang, "id" | "title">,
6+
lang?: Language,
7+
): string {
8+
const escapedTitle = encodeURIComponent(title);
9+
const restOfUrl = `${escapedTitle}-${id}`;
10+
11+
if (!lang) return `/contribute/${restOfUrl}`;
12+
13+
if (lang === DEFAULT_LANGUAGE) return `/contribute/${restOfUrl}`;
14+
15+
return `/${lang.code}/contribute/${restOfUrl}`;
816
}

web/src/utils/contributor.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { ContributorEntity } from "@dzcode.io/models/dist/contributor";
2+
import { DEFAULT_LANGUAGE, Language } from "@dzcode.io/models/dist/language";
23

3-
export function getContributorURL({ id }: Pick<ContributorEntity, "id">): string {
4-
return `/team/${id}`;
4+
export function getContributorURL({ id }: Pick<ContributorEntity, "id">, lang?: Language): string {
5+
if (!lang) return `/team/${id}`;
6+
7+
if (lang === DEFAULT_LANGUAGE) return `/team/${id}`;
8+
9+
return `/${lang.code}/team/${id}`;
510
}

0 commit comments

Comments
 (0)