diff --git a/packages/ui/src/dialog/__snapshots__/index.test.tsx.snap b/packages/ui/src/contributor-card/dialog/__snapshots__/index.test.tsx.snap similarity index 100% rename from packages/ui/src/dialog/__snapshots__/index.test.tsx.snap rename to packages/ui/src/contributor-card/dialog/__snapshots__/index.test.tsx.snap diff --git a/packages/ui/src/dialog/index.test.tsx b/packages/ui/src/contributor-card/dialog/index.test.tsx similarity index 71% rename from packages/ui/src/dialog/index.test.tsx rename to packages/ui/src/contributor-card/dialog/index.test.tsx index 908898aa2..79f52c15b 100644 --- a/packages/ui/src/dialog/index.test.tsx +++ b/packages/ui/src/contributor-card/dialog/index.test.tsx @@ -1,16 +1,16 @@ import { render, screen } from "@testing-library/react"; -import { createProjects } from "../__mocks__/create-projects"; -import { createRepositories } from "../__mocks__/create-repositories"; -import { ContributionsDialog } from "."; +import { createProjects } from "../../__mocks__/create-projects"; +import { createRepositories } from "../../__mocks__/create-repositories"; +import { ContributionsDialog, ContributionsDialogProps } from "."; it("should render a closed dialog on first mount", async () => { const onClose = jest.fn(); - const props = { + const props: ContributionsDialogProps = { onClose: onClose, open: false, - projects: createProjects(2), repositories: createRepositories(2), + repositoriesText: "Repositories", }; const { container } = render(); @@ -19,11 +19,11 @@ it("should render a closed dialog on first mount", async () => { it("should handle users with no projects", async () => { const onClose = jest.fn(); - const props = { + const props: ContributionsDialogProps = { onClose: onClose, open: true, - projects: [], repositories: createRepositories(2), + repositoriesText: "Repositories", }; render(); @@ -33,11 +33,11 @@ it("should handle users with no projects", async () => { it("should handle users with no repositories", async () => { const onClose = jest.fn(); - const props = { + const props: ContributionsDialogProps = { onClose: onClose, open: true, - projects: createProjects(2), repositories: [], + repositoriesText: "Repositories", }; render(); @@ -47,11 +47,11 @@ it("should handle users with no repositories", async () => { it("should render a dialog", async () => { const onClose = jest.fn(); - const props = { + const props: ContributionsDialogProps = { onClose: onClose, open: true, - projects: createProjects(2), repositories: createRepositories(2), + repositoriesText: "Repositories", }; render(); diff --git a/packages/ui/src/dialog/index.tsx b/packages/ui/src/contributor-card/dialog/index.tsx similarity index 67% rename from packages/ui/src/dialog/index.tsx rename to packages/ui/src/contributor-card/dialog/index.tsx index 135e7e211..54b683021 100644 --- a/packages/ui/src/dialog/index.tsx +++ b/packages/ui/src/contributor-card/dialog/index.tsx @@ -8,6 +8,7 @@ import ListItem from "@mui/material/ListItem"; import ListItemAvatar from "@mui/material/ListItemAvatar"; import ListItemText from "@mui/material/ListItemText"; import Typography from "@mui/material/Typography"; +import { FC } from "react"; interface ContributionItemProps { description: string; @@ -36,7 +37,7 @@ interface ContributionListProps { const ContributionList = ({ title, items }: ContributionListProps) => { return ( <> - + {title} @@ -48,66 +49,39 @@ const ContributionList = ({ title, items }: ContributionListProps) => { }; export interface ContributionsDialogProps { + repositoriesText: string; open: boolean; - projects?: Array<{ - slug: string; - image?: string; - title: string; - description?: string; - content?: string; - authors?: string[]; - contributors?: string[]; - views?: number; - githubURI?: string; - }>; repositories?: { provider: string; owner: string; repository: string }[]; onClose: () => void; } -export function ContributionsDialog(props: ContributionsDialogProps) { - const { onClose, open, projects, repositories } = props; - - const handleClose = () => { - onClose(); - }; - +export const ContributionsDialog: FC = ({ + onClose, + open, + repositories, + repositoriesText, +}) => { return ( - - - Contributions - - {repositories && repositories.length > 0 && ( ({ label: repository.repository, }))} /> )} - - {projects && projects.length > 0 && ( - ({ label: project.title }))} - /> - )} - ); -} +}; diff --git a/packages/ui/src/contributor-card/index.test.tsx b/packages/ui/src/contributor-card/index.test.tsx index 188e242d7..094fc16c2 100644 --- a/packages/ui/src/contributor-card/index.test.tsx +++ b/packages/ui/src/contributor-card/index.test.tsx @@ -13,7 +13,13 @@ it("should render a contributor skeleton ", async () => { it("should render a contributor card", () => { const contributor = createContributors(1)[0]; - render(); + render( + , + ); const username = screen.getByText(contributor.username); expect(username).toBeInTheDocument(); @@ -21,7 +27,13 @@ it("should render a contributor card", () => { it("should show contributions dialog after Contributions button is clicked", async () => { const contributor = createContributors(1)[0]; - render(); + render( + , + ); const button = await screen.findByRole("button", { name: "Contributions" }); userEvent.click(button); diff --git a/packages/ui/src/contributor-card/index.tsx b/packages/ui/src/contributor-card/index.tsx index 05df6b2a5..ad14dc617 100644 --- a/packages/ui/src/contributor-card/index.tsx +++ b/packages/ui/src/contributor-card/index.tsx @@ -9,7 +9,7 @@ import Skeleton from "@mui/material/Skeleton"; import Typography from "@mui/material/Typography"; import { FC, useState } from "react"; -import { ContributionsDialog } from "../dialog"; +import { ContributionsDialog } from "./dialog"; const styles = { root: { @@ -41,11 +41,17 @@ export const ContributorSkeleton = () => { ); }; -interface ContributorCardProps { +export interface ContributorCardProps { + ctaText: string; + repositoriesText: string; contributor: ContributorEntity; } -export const ContributorCard: FC = ({ contributor }) => { +export const ContributorCard: FC = ({ + contributor, + ctaText, + repositoriesText, +}) => { const [open, setOpen] = useState(false); const { avatarUrl, username, repositories } = contributor; return ( @@ -64,10 +70,15 @@ export const ContributorCard: FC = ({ contributor }) => { fullWidth variant="contained" > - Contributions + {ctaText} - setOpen(false)} /> + setOpen(false)} + /> ); }; diff --git a/packages/ui/src/faq-card/index.tsx b/packages/ui/src/faq-card/index.tsx index aae9f48c5..d322bfe3b 100644 --- a/packages/ui/src/faq-card/index.tsx +++ b/packages/ui/src/faq-card/index.tsx @@ -24,7 +24,7 @@ export const FaqCard = ({ title, questions }: FaqCardProps) => { {questions.map(({ question, answer }, index) => ( - + }> {question} diff --git a/packages/ui/src/translation-factory/index.tsx b/packages/ui/src/translation-factory/index.tsx new file mode 100644 index 000000000..92705a49b --- /dev/null +++ b/packages/ui/src/translation-factory/index.tsx @@ -0,0 +1,47 @@ +import type { VFC } from "react"; + +type BaseDictionary = Record>; + +export const translationFactory = + ( + dictionary: T, + getLanguageCode: () => keyof T[keyof T], + fallbackText = "MISSING_TRANSLATION", + ): VFC< + Partial> & { + k?: keyof T; + r?: Record; + } + > => + // eslint-disable-next-line react/display-name + ({ k, r = {}, ...props }) => { + const languageCode = getLanguageCode(); + const key = (k as keyof T) || (Object.keys(props)[0] as keyof T); + return <>{replace(dictionary, languageCode, fallbackText, key, r)}; + }; + +export const translationFunctionFactory = + >>( + dictionary: T, + getLanguageCode: () => keyof T[keyof T], + fallbackText?: string, + ): ((k: keyof T, r?: Record) => string) => + (k, r = {}) => { + const languageCode = getLanguageCode(); + return replace(dictionary, languageCode, fallbackText, k, r); + }; + +const replace = ( + dictionary: T, + languageCode: keyof T[keyof T], + fallbackText = "MISSING_TRANSLATION", + k: keyof T, + r: Record = {}, +) => { + const key = k; + let value = dictionary[key]?.[languageCode] || fallbackText; + Object.keys(r).forEach((rKey: keyof typeof r) => { + value = value.replace(RegExp(`${rKey}`), r[rKey]); + }); + return value; +}; diff --git a/web/package.json b/web/package.json index 35007ebd6..58e165295 100644 --- a/web/package.json +++ b/web/package.json @@ -26,8 +26,6 @@ "markdown-to-jsx": "^7.1.0", "react": "^17.0.1", "react-dom": "^17.0.1", - "react-intl": "^5.20.6", - "react-intl-translations-manager": "^5.0.3", "react-redux": "^7.2.6", "react-router-dom": "^5.2.0", "react-spring": "^8.0.27", diff --git a/web/src/apps/main/components/card/index.tsx b/web/src/apps/main/components/card/index.tsx index 4682f1019..0917e69cc 100644 --- a/web/src/apps/main/components/card/index.tsx +++ b/web/src/apps/main/components/card/index.tsx @@ -47,7 +47,7 @@ export const Card: FC = ({ info }) => { {info ? ( <> - + {info.title} diff --git a/web/src/apps/main/components/footer/__snapshots__/footer.spec.tsx.snap b/web/src/apps/main/components/footer/__snapshots__/footer.spec.tsx.snap index e2cba5cc8..7103d6b64 100644 --- a/web/src/apps/main/components/footer/__snapshots__/footer.spec.tsx.snap +++ b/web/src/apps/main/components/footer/__snapshots__/footer.spec.tsx.snap @@ -183,13 +183,14 @@ exports[`components/footer/footer.spec.tsx should render properly 1`] = `
- Contact Information + FAQ

+213 06-76-26-11-57

@@ -206,10 +207,12 @@ exports[`components/footer/footer.spec.tsx should render properly 1`] = `

- Copyright © - 2020 + Copyright © + + 2022 @dzCode_io diff --git a/web/src/apps/main/components/footer/footer.spec.tsx b/web/src/apps/main/components/footer/footer.spec.tsx index 219c84b3a..09019fedc 100644 --- a/web/src/apps/main/components/footer/footer.spec.tsx +++ b/web/src/apps/main/components/footer/footer.spec.tsx @@ -1,5 +1,4 @@ import { render } from "@testing-library/react"; -import { IntlProvider } from "react-intl"; import { Provider } from "react-redux"; import { BrowserRouter as Router } from "react-router-dom"; import { createMainStore } from "src/apps/main/redux"; @@ -13,9 +12,7 @@ describe("components/footer/footer.spec.tsx", () => { const { container } = render( - -