Skip to content

Commit

Permalink
introduction of I18n and fixes (#49)
Browse files Browse the repository at this point in the history
* introduction of I18n and fixes

* fix

* fix in useCampaign campaign name

* lint
  • Loading branch information
hugolxt authored Dec 19, 2024
1 parent de6c327 commit 181c9c1
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 26 deletions.
23 changes: 14 additions & 9 deletions merkl.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ export default createConfig({
appName: "Merkl",
modes: ["dark", "light"],
defaultTheme: "ignite",
tags: [],
opportunityNavigationMode: "direct",
rewardsNavigationMode: "chain",
opprtunityPercentage: true,
deposit: true,
themes: {
ignite: {
Expand Down Expand Up @@ -95,16 +95,16 @@ export default createConfig({
route: "/",
key: uuidv4(),
},
opportunities: {
icon: "RiPlanetFill",
route: "/opportunities",
key: uuidv4(),
},
// protocols: {
// icon: "RiVipCrown2Fill",
// route: "/protocols",
// opportunities: {
// icon: "RiPlanetFill",
// route: "/opportunities",
// key: uuidv4(),
// },
protocols: {
icon: "RiVipCrown2Fill",
route: "/protocols",
key: uuidv4(),
},
// bridge: {
// icon: "RiCompassesLine",
// route: "/bridge",
Expand Down Expand Up @@ -132,6 +132,11 @@ export default createConfig({
// key: uuidv4(),
// },
},
header: {
searchbar: {
enabled: true,
},
},
socials: {
discord: "",
telegram: "https://t.me/+2T0RNabX2ANkMzAx",
Expand Down
14 changes: 14 additions & 0 deletions src/I18n/en.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const en = {
pages: {
opportunities: {
title: "Explore opportunities",
description: "Browse opportunities, compare rewards, and earn tokens",
},
campaings: {
title: "Explore opportunities",
description: "Browse opportunities, compare rewards, and earn tokens",
},
},
};

export default en;
34 changes: 34 additions & 0 deletions src/I18n/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import en from "./en";

type LanguageFiles = typeof en;

/**
* I18n class to handle translations
*/
export class I18n {
public static readonly trad: I18n = new I18n(en);

private primary: LanguageFiles;
// private secondary: LanguageFiles;

public get: LanguageFiles;

constructor(primary: LanguageFiles) {
this.primary = primary;
// this.secondary = secondary;
this.get = this.createProxy(this.primary);
}

// proxy to handle typing autocompletion
private createProxy<T extends object>(obj: T): T {
return new Proxy(obj, {
get: (target, prop) => {
const value = target[prop as keyof T];
if (typeof value === "object" && value !== null) {
return this.createProxy(value as object);
}
return value;
},
});
}
}
4 changes: 3 additions & 1 deletion src/components/element/functions/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ function OpportunityResult({ opportunity }: { opportunity: Opportunity }) {
return (
<>
<Button to={link} look="soft">
<Icons>{icons}</Icons> {opportunity.name} <Icon remix="RiArrowRightLine" />
<Icons>{icons}</Icons>
{opportunity.name}
<Icon remix="RiArrowRightLine" />
</Button>
<Divider look="soft" />
</>
Expand Down
7 changes: 6 additions & 1 deletion src/components/element/opportunity/OpportunityTableRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Link } from "@remix-run/react";
import type { BoxProps } from "dappkit";
import { Dropdown, Group, Icon, Icons, PrimitiveTag, Text, Title, Value } from "dappkit";
import { mergeClass } from "dappkit";
import config from "merkl.config";
import { useOverflowingRef } from "packages/dappkit/src/hooks/events/useOverflowing";
import { useMemo } from "react";
import type { OpportunityNavigationMode } from "src/config/opportunity";
Expand Down Expand Up @@ -115,7 +116,11 @@ export default function OpportunityTableRow({
"text-nowrap whitespace-nowrap text-ellipsis min-w-0 inline-block overflow-hidden",
overflowing && "hover:overflow-visible hover:animate-textScroll hover:text-clip",
)}>
<span className="overflow-visible">{opportunity.name}</span>
<span className="overflow-visible">
{config.opprtunityPercentage
? opportunity.name
: opportunity.name.replace(/\s*\d+(\.\d+)?%$/, "").trim()}
</span>
</Title>
</Group>
</Group>
Expand Down
2 changes: 1 addition & 1 deletion src/components/element/tvl/TvlSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export default function TvlSection({ opportunity }: TvlSectionProps) {
</PrimitiveTag>
)}
<Text look="bold" className="inline-flex justify-end" size="sm">
<Value value format="0a">
<Value value format="0.###a">
{breakdown.value}
</Value>
</Text>
Expand Down
4 changes: 2 additions & 2 deletions src/components/layout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default function Header() {
return Object.assign(
{ home },
{
claims: {
dashboard: {
icon: "RiDashboardFill",
route: user ? `/users/${user}` : "/users",
key: uuidv4(),
Expand Down Expand Up @@ -97,7 +97,7 @@ export default function Header() {
})}
<Group className="items-center">
<SwitchMode />
<SearchBar icon={true} />
{config.header.searchbar.enabled && <SearchBar icon={true} />}
</Group>
</Group>

Expand Down
6 changes: 6 additions & 0 deletions src/config/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,17 @@ export type MerklConfig<T extends Themes> = {
deposit?: boolean;
opportunityNavigationMode?: OpportunityNavigationMode;
rewardsNavigationMode?: RewardsNavigationMode;
opprtunityPercentage: boolean;
modes: Mode[];
wagmi: Parameters<typeof createWagmiConfig>["0"];
appName: string;
fonts?: { title: string[]; text: string[]; mono: string[] };
routes: routesType;
header: {
searchbar: {
enabled: boolean;
};
};
images: {
[name: string]: string;
};
Expand Down
6 changes: 5 additions & 1 deletion src/hooks/resources/useOpportunity.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Opportunity } from "@merkl/api";
import type { Token } from "@merkl/api";
import { Icon, Value } from "dappkit";
import config from "merkl.config";
import { useMemo } from "react";
import type { TagType } from "src/components/element/Tag";
import { v4 as uuidv4 } from "uuid";
Expand Down Expand Up @@ -134,7 +135,10 @@ export default function useOpportunity(opportunity: Opportunity) {
rewardIcons,
description,
rewardsBreakdown,
...opportunity,
opportunity: {
...opportunity,
name: config.opprtunityPercentage ? opportunity.name : opportunity.name.replace(/\s*\d+(\.\d+)?%$/, "").trim(),
},
tags,
herosData,
};
Expand Down
5 changes: 3 additions & 2 deletions src/routes/_merkl.(home).tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { MetaFunction } from "@remix-run/node";
import { Outlet } from "@remix-run/react";
import { I18n } from "src/I18n";
import Hero from "src/components/composite/Hero";

export const meta: MetaFunction = () => {
Expand All @@ -11,8 +12,8 @@ export default function Index() {
<Hero
icons={[{ remix: "RiPlanetFill" }]}
navigation={{ label: "Back to opportunities", link: "/" }}
title={"Explore opportunities"}
description={"Browse opportunities, compare rewards, and earn tokens"}>
title={I18n.trad.get.pages.opportunities.title}
description={I18n.trad.get.pages.opportunities.description}>
<Outlet />
</Hero>
);
Expand Down
25 changes: 16 additions & 9 deletions src/routes/_merkl.opportunities.$chain.$type.$id.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Chain } from "@merkl/api";
import { type LoaderFunctionArgs, type MetaFunction, json } from "@remix-run/node";
import { Meta, Outlet, useLoaderData } from "@remix-run/react";
import config from "merkl.config";
import { useMemo } from "react";
import { Cache } from "src/api/services/cache.service";
import { ChainService } from "src/api/services/chain.service";
Expand All @@ -17,20 +18,23 @@ export async function loader({ params: { id, type, chain: chainId } }: LoaderFun

const chain = await ChainService.get({ search: chainId });

const opportunity = await OpportunityService.getCampaignsByParams({
const rawOpportunity = await OpportunityService.getCampaignsByParams({
chainId: chain.id,
type: type,
identifier: id,
});

return json({ opportunity, chain });
return json({ rawOpportunity, chain });
}

export const clientLoader = Cache.wrap("opportunity", 300);

export const meta: MetaFunction<typeof loader> = ({ data, error }) => {
if (error) return [{ title: error }];
return [{ title: `${data?.opportunity.name} on Merkl` }];
return [
{
title: `${data?.rawOpportunity.name} on Merkl`,
},
];
};

export type OutletContextOpportunity = {
Expand All @@ -39,11 +43,11 @@ export type OutletContextOpportunity = {
};

export default function Index() {
const { opportunity, chain } = useLoaderData<typeof loader>();
const { tags, description, link, herosData } = useOpportunity(opportunity);
const { rawOpportunity, chain } = useLoaderData<typeof loader>();
const { tags, description, link, herosData, opportunity } = useOpportunity(rawOpportunity);

const styleName = useMemo(() => {
const spaced = opportunity?.name.split(" ");
const spaced = opportunity.name.split(" ");

return spaced
.map(str => {
Expand Down Expand Up @@ -75,8 +79,11 @@ export default function Index() {
<Hero
icons={opportunity.tokens.map(t => ({ src: t.icon }))}
breadcrumbs={[
{ link: "/", name: "Opportunities" },
{ link: "/", name: opportunity.name },
{ link: config.routes.opportunities?.route ?? "/", name: "Opportunities" },
{
link: "/",
name: opportunity.name,
},
]}
title={styleName}
description={description}
Expand Down

0 comments on commit 181c9c1

Please sign in to comment.