Merge pull request 'feature/russian-localization' (#145) from feature/russian-localization into develop

Reviewed-on: http://85.143.176.51:3000/free-land/front-end/pulls/145
This commit is contained in:
Daniel Weissmall 2022-10-14 11:21:14 +00:00
commit 49d15e538b
17 changed files with 198 additions and 94 deletions

View File

@ -59,5 +59,70 @@
"services": { "services": {
"fork": "Не удалось выполнить авторизацию в сервисе" "fork": "Не удалось выполнить авторизацию в сервисе"
} }
},
"articlePage": {
"abstract": "Введение",
"keywords": "Ключевые слова"
},
"navbar": {
"createNew": "Создать статью",
"about": {
"navTitle": "О проекте",
"aboutProject": "О Scipaper",
"contacts": "Контакты",
"help": "Помощь"
},
"library": {
"navTitle": "Моя библиотека",
"publications": "Публикации",
"favorites": "Избранное",
"collections": "Коллекции",
"recentViewed": "История"
},
"auth": {
"signIn": "Вход",
"signUp": "Регистрация"
} }
},
"footer": {
"accountSettings": "Настройки аккаунта",
"about": "О scipaper",
"help": "Помощь",
"contactUs": "Контакты",
"allRightsReserved": "Все права защищены",
"termsOfUse": "Правила использования",
"privacyPolicy": "Политика конфиденциальности",
"coockiesPolicy": "Политика использования coockies",
"supportedBy": "Создано"
},
"mainPage": {
"title": "Библиотека научных статей с бесплатным доступом",
"search": "Поиск",
"article_one": "статьи",
"article_few": "статей",
"article_many": "статей",
"advancedSearch": "Расширенный поиск",
"featuredArticles": {
"title": "Популярные статьи",
"descriptionPart1": "Выберете интересующую вас ",
"descriptionPart2": "научную категорию",
"categories": {
"Medical": "Медицина",
"TechnicsAndTechlonogies": "Техника и технологии",
"Fundamental": "Естественые",
"Humanitarian": "Гуманитарные",
"Agricultural": "Аuрокультурa",
"Social": "Социальные"
}
},
"featuredAuthors": "Популярные авторы",
"more": "Больше",
"showAll": "Показать все"
},
"searchResults": {
"title": "Результаты поиска",
"totalResults":"Всего найдено",
"nothingFound": "Ничего не найдено"
}
} }

View File

@ -37,7 +37,7 @@ export const ArticleSearchResult = ({ searchItem }: Props) => {
<Article.SubscriptionsButtons /> <Article.SubscriptionsButtons />
</div> </div>
<Article.Title linkTo={searchItem.id} className="text-2xl"> <Article.Title linkTo={`/article/${searchItem.id}`} className="text-2xl">
{searchItem.title} {searchItem.title}
</Article.Title> </Article.Title>
<Article.Authors emphasis="low" className="flex flex-wrap flex-row"> <Article.Authors emphasis="low" className="flex flex-wrap flex-row">

View File

@ -3,7 +3,7 @@ import { SVGMedicine } from "../icons";
import Typography from "components/typography/Typography"; import Typography from "components/typography/Typography";
import { Button } from "components/Button/Button"; import { Button } from "components/Button/Button";
import classNames from "classnames"; import classNames from "classnames";
import { JsxElement } from "typescript"; import { useTranslation } from "react-i18next";
type Props = { type Props = {
count?: number; count?: number;
@ -13,6 +13,7 @@ type Props = {
} & Omit<React.ComponentPropsWithoutRef<"div">, "">; } & Omit<React.ComponentPropsWithoutRef<"div">, "">;
function CategoryCard({ count, title, iconChild, className, ...props }: Props) { function CategoryCard({ count, title, iconChild, className, ...props }: Props) {
const [t, i18next] = useTranslation()
const iconChildStyle = const iconChildStyle =
"h-7 fill-gray-500 stroke-gray-500 group-focus:fill-blue-600 group-active:fill-blue-600 group-focus:stroke-blue-600 group-active:stroke-blue-600"; "h-7 fill-gray-500 stroke-gray-500 group-focus:fill-blue-600 group-active:fill-blue-600 group-focus:stroke-blue-600 group-active:stroke-blue-600";
@ -34,7 +35,7 @@ function CategoryCard({ count, title, iconChild, className, ...props }: Props) {
fontWeightVariant="bold" fontWeightVariant="bold"
className="text-sm leading-6 min-w-max group-active:text-blue-600 group-focus:text-blue-600" className="text-sm leading-6 min-w-max group-active:text-blue-600 group-focus:text-blue-600"
> >
{title} {t(title)}
</Typography> </Typography>
</div> </div>
<div className="max-w-max "> <div className="max-w-max ">
@ -42,7 +43,7 @@ function CategoryCard({ count, title, iconChild, className, ...props }: Props) {
fontWeightVariant="normal" fontWeightVariant="normal"
className="text-xs text-gray-500 group-active:text-blue-600 group-focus:text-blue-600" className="text-xs text-gray-500 group-active:text-blue-600 group-focus:text-blue-600"
> >
{count} Items {count} {t("mainPage.article", {count: count}).toString()}
</Typography> </Typography>
</div> </div>
</div> </div>

View File

@ -31,6 +31,7 @@ import "swiper/css/pagination";
import "swiper/css/navigation"; import "swiper/css/navigation";
// import "./styles.css"; // import "./styles.css";
import "swiper/css"; import "swiper/css";
import { useTranslation } from "react-i18next";
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Article mock data */ /* Article mock data */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -97,6 +98,7 @@ const FeaturedArticlesCards = () => {
const navigationPrevRef = useRef(null); const navigationPrevRef = useRef(null);
const navigationNextRef = useRef(null); const navigationNextRef = useRef(null);
const paginationRef = useRef(null); const paginationRef = useRef(null);
const [t, i18next] = useTranslation()
return ( return (
<div className="slider-wrapper articles"> <div className="slider-wrapper articles">
@ -168,7 +170,7 @@ const FeaturedArticlesCards = () => {
<Card.CardAction href={Articale.Link}> <Card.CardAction href={Articale.Link}>
<Link to="*"> <Link to="*">
<Typography className="text-blue-500 font-bold"> <Typography className="text-blue-500 font-bold">
Read More {t("mainPage.more")}
</Typography> </Typography>
</Link> </Link>
<SVGCaretRight className="fill-blue-500 w-4 h-4" /> <SVGCaretRight className="fill-blue-500 w-4 h-4" />

View File

@ -9,22 +9,25 @@ import {
SVGTechnicsAndTechology, SVGTechnicsAndTechology,
SVGFundamental, SVGFundamental,
} from "components/icons"; } from "components/icons";
import { useTranslation} from "react-i18next";
const categories = [ const categories = [
{ id: 1, title: "Medical", count: 5617813, icon: <SVGMedicine /> }, { id: 1, title: "mainPage.featuredArticles.categories.Medical", count: 5617813, icon: <SVGMedicine /> },
{ {
id: 2, id: 2,
title: "Technics and Technology", title: "mainPage.featuredArticles.categories.TechnicsAndTechlonogies",
count: 5617813, count: 5617813,
icon: <SVGTechnicsAndTechology />, icon: <SVGTechnicsAndTechology />,
}, },
{ id: 3, title: "Fundamental", count: 5617813, icon: <SVGFundamental /> }, { id: 3, title: "mainPage.featuredArticles.categories.Fundamental", count: 5617813, icon: <SVGFundamental /> },
{ id: 4, title: "Humanitarian", count: 5617813, icon: <SVGHumanitarian /> }, { id: 4, title: "mainPage.featuredArticles.categories.Humanitarian", count: 5617813, icon: <SVGHumanitarian /> },
{ id: 5, title: "Agricultural", count: 5617813, icon: <SVGAgricultural /> }, { id: 5, title: "mainPage.featuredArticles.categories.Agricultural", count: 5617813, icon: <SVGAgricultural /> },
{ id: 6, title: "Social", count: 5617813, icon: <SVGSocials /> }, { id: 6, title: "mainPage.featuredArticles.categories.Social", count: 5617813, icon: <SVGSocials /> },
]; ];
export function FeaturedArticlesCategories() { export function FeaturedArticlesCategories() {
const [t, i18next] = useTranslation();
const categoryCards = useMemo( const categoryCards = useMemo(
() => () =>
categories.map((category) => ( categories.map((category) => (
@ -45,11 +48,11 @@ export function FeaturedArticlesCategories() {
fontWeightVariant="semibold" fontWeightVariant="semibold"
className="text-3xl mb-2" className="text-3xl mb-2"
> >
Featured articles {t("mainPage.featuredArticles.title")}
</Typography> </Typography>
<Typography htmlTag="h2" className="text-base text-gray-500"> <Typography htmlTag="h2" className="text-base text-gray-500">
Select the category of science <br className="visible sm:hidden" /> {t("mainPage.featuredArticles.descriptionPart1")}<br className="visible sm:hidden" />
you are interested in {t("mainPage.featuredArticles.descriptionPart2")}
</Typography> </Typography>
</div> </div>
<div className="py-8 px-10 flex md:flex justify-start md:justify-center md:flex-wrap overflow-x-scroll md:overflow-hidden snap-x scroll-smooth overscroll-x-contain"> <div className="py-8 px-10 flex md:flex justify-start md:justify-center md:flex-wrap overflow-x-scroll md:overflow-hidden snap-x scroll-smooth overscroll-x-contain">

View File

@ -17,12 +17,9 @@ import "swiper/css/navigation";
// import "./styles.css"; // import "./styles.css";
import "swiper/css"; import "swiper/css";
/* -------------------------------------------------------------------------- */
/* Icons */
/* -------------------------------------------------------------------------- */
import { ReactComponent as SVGCaretRight } from "assets/svg/caret-right.svg"; import { ReactComponent as SVGCaretRight } from "assets/svg/caret-right.svg";
import Link from "../../typography/Link"; import Link from "../../typography/Link";
import { useTranslation } from "react-i18next";
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Variables */ /* Variables */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -73,10 +70,12 @@ if (authors.length == 2) {
* Featured authors component to display ... * Featured authors component to display ...
*/ */
export default function FeaturedAuthorsCards(): JSX.Element { export default function FeaturedAuthorsCards(): JSX.Element {
const [t, i18next] = useTranslation();
return ( return (
<div> <div>
{/* The Title of Featured Authors section */} {/* The Title of Featured Authors section */}
<Heading className="text-center my-8">Featured Authors</Heading> <Heading className="text-center my-8 text-3xl font-semibold">{t("mainPage.featuredAuthors")}</Heading>
{/* Featured Authors section */} {/* Featured Authors section */}
<div className="slider-wrapper Authors"> <div className="slider-wrapper Authors">
@ -134,7 +133,7 @@ export default function FeaturedAuthorsCards(): JSX.Element {
<Card.CardAction href={card.Link}> <Card.CardAction href={card.Link}>
<Link className="text-blue-500 font-bold" to="*"> <Link className="text-blue-500 font-bold" to="*">
See More {t('mainPage.more')}
</Link> </Link>
<SVGCaretRight className="fill-blue-500 w-4 h-4" /> <SVGCaretRight className="fill-blue-500 w-4 h-4" />
</Card.CardAction> </Card.CardAction>
@ -188,7 +187,7 @@ export default function FeaturedAuthorsCards(): JSX.Element {
</div> </div>
<Button emphasis="high" className="font-bold m-auto my-8"> <Button emphasis="high" className="font-bold m-auto my-8">
Show All {t("mainPage.showAll")}
</Button> </Button>
</div> </div>
); );

View File

@ -2,24 +2,32 @@
/* Imports */ /* Imports */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
import React from "react"; import React from "react";
import {t as nextT} from "i18next";
import { useTranslation } from "react-i18next";
import { SearchBar } from "../../search/SearchBar"; import { SearchBar } from "../../search/SearchBar";
import { formatNumber } from "core/helpers";
export default function MainSection() { export default function MainSection() {
const { t, i18n } = useTranslation();
const amountArticles = 4202020
return ( return (
<section className="bg-main bg-center bg-cover bg-origin-border bg-no-repeat min-h-[100vh] py-32 px-2 sm:px-6 md:px-6 lg:px-0 items-center flex justify-center "> <section className="bg-main bg-center bg-cover bg-origin-border bg-no-repeat min-h-[100vh] py-32 px-2 sm:px-6 md:px-6 lg:px-0 items-center flex justify-center ">
<div className="flex-col"> <div className="flex-col">
<div className="m-auto text-center font-bold text-4xl "> <div className="m-auto text-center font-bold text-4xl ">
Scientific Library with Free Access {t("mainPage.title")}
</div> </div>
<div className="flex flex-row items-center justify-center space-x-3 pt-2"> <div className="flex flex-row items-center justify-center space-x-3 pt-2">
<div className=" text-2xl text-gray-400">Search</div> <div className=" text-2xl text-gray-400">{t("mainPage.search")}</div>
<div className=" text-3xl text-blue-500">320 455</div> <div className=" text-3xl text-blue-500">{formatNumber(amountArticles)}</div>
<div className=" text-2xl text-gray-400">Items</div> <div className=" text-2xl text-gray-400">{nextT("mainPage.article", {count: amountArticles}).toString()}</div>
</div> </div>
<div className="max-w-xl m-auto pt-16 "> <div className="max-w-xl m-auto pt-16 ">
<SearchBar /> <SearchBar />
<div className="mt-7 pr-1 text-right font-semibold text-sm"> <div className="mt-7 pr-1 text-right font-semibold text-sm">
Advanced Search {t("mainPage.advancedSearch")}
</div> </div>
</div> </div>
</div> </div>

View File

@ -4,10 +4,12 @@ import { useSearchStoreImplementation } from "searchResults/data/searchStoreImpl
import { useSearchViewModel } from "../searchResults/controller/searchResultsViewModel"; import { useSearchViewModel } from "../searchResults/controller/searchResultsViewModel";
import { ArticleSearchResult } from "./ArticleSearchResult"; import { ArticleSearchResult } from "./ArticleSearchResult";
import { Loader } from "./Loader/Loader"; import { Loader } from "./Loader/Loader";
import { useTranslation } from "react-i18next";
export const SearchResultSection = () => { export const SearchResultSection = () => {
const store = useSearchStoreImplementation(); const store = useSearchStoreImplementation();
const { searchResults, isLoading } = useSearchViewModel(store); const { searchResults, isLoading } = useSearchViewModel(store);
const [t, i18next] = useTranslation()
function getResults() { function getResults() {
if (searchResults === undefined || searchResults?.data.length === 0) { if (searchResults === undefined || searchResults?.data.length === 0) {
@ -16,7 +18,7 @@ export const SearchResultSection = () => {
fontWeightVariant="semibold" fontWeightVariant="semibold"
className="text-xl w-full text-center items-center py-3" className="text-xl w-full text-center items-center py-3"
> >
Nothing found. {t("searchResults.nothingFound")}.
</Typography> </Typography>
); );
} else { } else {
@ -31,10 +33,10 @@ export const SearchResultSection = () => {
<div className="p-4 md:px-6 md:py-8"> <div className="p-4 md:px-6 md:py-8">
<div className="pb-2"> <div className="pb-2">
<Typography fontWeightVariant="semibold" className="text-3xl"> <Typography fontWeightVariant="semibold" className="text-3xl">
Search Results {t("searchResults.title")}
</Typography> </Typography>
<Typography className="text-gray-300 text-sm"> <Typography className="text-gray-300 text-sm">
Total results: {searchResults?.meta.total} {t("searchResults.totalResults")}: {searchResults?.meta.total}
</Typography> </Typography>
</div> </div>
<hr className="w-full border-gray-100" /> <hr className="w-full border-gray-100" />

View File

@ -8,10 +8,13 @@ import Container from "components/Container";
import NotFound from "./NotFound"; import NotFound from "./NotFound";
import { SVGSearch } from "components/icons"; import { SVGSearch } from "components/icons";
import BaseLayout from "components/BaseLayout"; import BaseLayout from "components/BaseLayout";
import Typography from "components/typography/Typography";
import { useTranslation } from "react-i18next";
const AnArticle = () => { const AnArticle = () => {
const store = useArticleStore(); const store = useArticleStore();
const { article, hasError, shouldShowLoading } = useArticleViewModel(store); const { article, hasError, shouldShowLoading } = useArticleViewModel(store);
const { i18n, t } = useTranslation();
const { id } = useParams(); const { id } = useParams();
const newId = `${id}`; const newId = `${id}`;
@ -46,9 +49,13 @@ const AnArticle = () => {
<ArticlePart.Article.InteractionButtons emphasis="high" /> <ArticlePart.Article.InteractionButtons emphasis="high" />
{article?.tags && ( {article?.tags && (
<div className="keywords my-10 flex flex-col gap-2"> <div className="keywords my-10 flex flex-col gap-2">
<ArticlePart.Article.Title className="text-2xl"> <Typography
Keywords className="text-2xl"
</ArticlePart.Article.Title> fontWeightVariant="semibold"
>
{t('articlePage.keywords')}
</Typography>
<ArticlePart.Article.Keywords className="transition ease-in-out delay-50"> <ArticlePart.Article.Keywords className="transition ease-in-out delay-50">
{article?.tags} {article?.tags}
@ -56,9 +63,12 @@ const AnArticle = () => {
</div> </div>
)} )}
<div className="abstract my-10 flex flex-col gap-2"> <div className="abstract my-10 flex flex-col gap-2">
<ArticlePart.Article.Title className="text-2xl"> <Typography
Abstract className="text-2xl"
</ArticlePart.Article.Title> fontWeightVariant="semibold"
>
{t('articlePage.abstract')}
</Typography>
<ArticlePart.Article.Description> <ArticlePart.Article.Description>
{article?.summary !== undefined ? ( {article?.summary !== undefined ? (
article?.summary article?.summary

View File

@ -6,29 +6,29 @@ import Typography from "components/typography/Typography";
import { SVGFacebook, SVGInstagram, SVGCircle } from "components/icons"; import { SVGFacebook, SVGInstagram, SVGCircle } from "components/icons";
import { RouterLink } from "components/typography/RouterLink"; import { RouterLink } from "components/typography/RouterLink";
import Link from "components/typography/Link"; import Link from "components/typography/Link";
import { useTranslation } from "react-i18next";
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Define consts */ /* Define consts */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
const mainLinks = [ const mainLinks = [
{ label: "account settings", url: "/account/settings", disabled: false }, { label: "footer.accountSettings", url: "/account/settings", disabled: false },
{ label: "about freeland", url: "/about", disabled: false }, { label: "footer.about", url: "/about", disabled: false },
{ label: "help", url: "/help", disabled: false }, { label: "footer.help", url: "/help", disabled: false },
{ label: "contact us", url: "/contact-us", disabled: false }, { label: "footer.contactUs", url: "/contact-us", disabled: false },
]; ];
const secondaryLinks = [ const secondaryLinks = [
{ index: 1, label: "Terms of Use", url: "/terms-of-use", disabled: false }, { index: 1, label: "footer.termsOfUse", url: "/terms-of-use", disabled: false },
{ {
index: 2, index: 2,
label: "Privacy Policy", label: "footer.privacyPolicy",
url: "/privacy-policy", url: "/privacy-policy",
disabled: false, disabled: false,
}, },
{ {
index: 3, index: 3,
label: "Cookies Policy", label: "footer.coockiesPolicy",
url: "/cookies-policy", url: "/cookies-policy",
disabled: false, disabled: false,
}, },
@ -48,6 +48,8 @@ const circleDivider = (
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
export function Footer() { export function Footer() {
const { t, i18n } = useTranslation();
/* -------------------------- Part with main links -------------------------- */ /* -------------------------- Part with main links -------------------------- */
const mainLinksPart = useMemo( const mainLinksPart = useMemo(
() => () =>
@ -59,7 +61,7 @@ export function Footer() {
to={link.url} to={link.url}
> >
<Typography className="" fontWeightVariant="semibold" htmlTag="p"> <Typography className="" fontWeightVariant="semibold" htmlTag="p">
{link.label.toUpperCase()} {t(link.label).toUpperCase()}
</Typography> </Typography>
</RouterLink> </RouterLink>
)), )),
@ -72,7 +74,7 @@ export function Footer() {
<div className="flex flex-row items-center"> <div className="flex flex-row items-center">
{link.index != 1 && circleDivider} {link.index != 1 && circleDivider}
<Link key={link.url} disabled={link.disabled} to={link.url}> <Link key={link.url} disabled={link.disabled} to={link.url}>
{link.label} {t(link.label) }
</Link> </Link>
</div> </div>
)), )),
@ -88,7 +90,7 @@ export function Footer() {
<div className="sm:col-span-1"> <div className="sm:col-span-1">
<Link to="*"> <Link to="*">
<Typography className="text-2xl" fontWeightVariant="semibold"> <Typography className="text-2xl" fontWeightVariant="semibold">
Freeland Scipaper
</Typography> </Typography>
</Link> </Link>
</div> </div>
@ -108,13 +110,13 @@ export function Footer() {
<section className="w-full flex flex-col md:flex-row text-gray-500 text-xs justify-between"> <section className="w-full flex flex-col md:flex-row text-gray-500 text-xs justify-between">
<div className="flex flex-col md:flex-row justify-center items-center"> <div className="flex flex-col md:flex-row justify-center items-center">
<Typography> <Typography>
@ Copyright 2022 Freeland - All rights reserved @ Copyright 2022 Freeland - {t("footer.allRightsReserved")}
</Typography> </Typography>
<div className="hidden md:flex">{circleDivider}</div> <div className="hidden md:flex">{circleDivider}</div>
<div className="flex flex-row items-center">{secondaryLinksPart}</div> <div className="flex flex-row items-center">{secondaryLinksPart}</div>
</div> </div>
<div className="flex flex-row justify-center md:justify-end"> <div className="flex flex-row justify-center md:justify-end">
Supported by {t("footer.supportedBy")}
<Typography className="ml-1 lg:ml-2" fontWeightVariant="bold"> <Typography className="ml-1 lg:ml-2" fontWeightVariant="bold">
Comfortel Comfortel
</Typography> </Typography>

View File

@ -1,5 +1,5 @@
import classNames from "classnames"; import classNames from "classnames";
import { useState } from "react"; import { useState, useTransition } from "react";
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Components */ /* Components */
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -23,11 +23,14 @@ import {
SVGFile, SVGFile,
SVGEye, SVGEye,
} from "components/icons"; } from "components/icons";
import i18n from "localization/i18n";
import { useTranslation } from "react-i18next";
const Header = () => { const Header = () => {
const [authenticated, setAuthenticated] = useState(false); const [authenticated, setAuthenticated] = useState(false);
const onClick = () => setAuthenticated(true); const onClick = () => setAuthenticated(true);
const [notification, setNotification] = useState(false); const [notification, setNotification] = useState(false);
const { t, i18n } = useTranslation();
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Implement Header Component */ /* Implement Header Component */
@ -66,36 +69,36 @@ const Header = () => {
className="text-blue-500 px-4 font-bold uppercase" className="text-blue-500 px-4 font-bold uppercase"
to="/create-new" to="/create-new"
> >
Create new {t('navbar.createNew')}
</RouterLink> </RouterLink>
{/* Link Create now - end - */} {/* Link Create now - end - */}
{/* Dropdown Menu My library - start - */} {/* Dropdown Menu My library - start - */}
<ContextMenu <ContextMenu
emphasis="high" emphasis="high"
button="My library" button={t('navbar.library.navTitle')}
className="border-none uppercase" className="border-none uppercase"
> >
<ContextMenuAction <ContextMenuAction
caption="My Publications" caption={t('navbar.library.publications')}
action={() => console.log("My publications")} action={() => console.log("My publications")}
icon={<SVGFile className="stroke-black " />} icon={<SVGFile className="stroke-black " />}
></ContextMenuAction> ></ContextMenuAction>
<ContextMenuAction <ContextMenuAction
caption="My Favorites" caption={t('navbar.library.favorites')}
action={() => console.log("My Favorites")} action={() => console.log("My Favorites")}
icon={<SVGFavoriteOutlined className="stroke-black" />} icon={<SVGFavoriteOutlined className="stroke-black" />}
></ContextMenuAction> ></ContextMenuAction>
<ContextMenuAction <ContextMenuAction
caption="My Collections" caption={t('navbar.library.collections')}
action={() => console.log("My Collections")} action={() => console.log("My Collections")}
icon={<SVGFolder className="stroke-black fill-black" />} icon={<SVGFolder className="stroke-black fill-black" />}
></ContextMenuAction> ></ContextMenuAction>
<ContextMenuAction <ContextMenuAction
caption="Recent Viewed" caption={t('navbar.library.recentViewed')}
action={() => console.log("Recent Viewed")} action={() => console.log("Recent Viewed")}
icon={<SVGEye className="stroke-black " />} icon={<SVGEye className="stroke-black " />}
></ContextMenuAction> ></ContextMenuAction>
@ -105,21 +108,21 @@ const Header = () => {
{/* Dropdown Menu About - start - */} {/* Dropdown Menu About - start - */}
<ContextMenu <ContextMenu
emphasis="high" emphasis="high"
button="About" button={t('navbar.about.navTitle')}
className="border-none uppercase" className="border-none uppercase"
> >
<ContextMenuAction <ContextMenuAction
caption="About Freeland" caption={t('navbar.about.aboutProject')}
action={() => console.log("About Freeland")} action={() => console.log("About Freeland")}
></ContextMenuAction> ></ContextMenuAction>
<ContextMenuAction <ContextMenuAction
caption="Contact Us" caption={t('navbar.about.contacts')}
action={() => console.log("Contact Us")} action={() => console.log("Contact Us")}
></ContextMenuAction> ></ContextMenuAction>
<ContextMenuAction <ContextMenuAction
caption="Help" caption={t('navbar.about.help')}
action={() => console.log("Help")} action={() => console.log("Help")}
></ContextMenuAction> ></ContextMenuAction>
</ContextMenu> </ContextMenu>
@ -137,14 +140,14 @@ const Header = () => {
onClick={onClick} onClick={onClick}
className="text-xs sm:px-4 sm:text-sm " className="text-xs sm:px-4 sm:text-sm "
> >
Sign in {t('navbar.auth.signIn')}
</Button>, </Button>,
<Button <Button
emphasis="medium" emphasis="medium"
className="hidden md:flex" className="hidden md:flex"
onClick={onClick} onClick={onClick}
> >
Sign up {t('navbar.auth.signUp')}
</Button>, </Button>,
] ]
: [ : [

View File

@ -4,6 +4,7 @@ import SearchInput from "./SearchInput";
import { Button } from "components/Button/Button"; import { Button } from "components/Button/Button";
import { SVGSearch } from "components/icons"; import { SVGSearch } from "components/icons";
import Link from "components/typography/Link"; import Link from "components/typography/Link";
import { useTranslation } from "react-i18next";
type Props = { type Props = {
@ -15,6 +16,8 @@ type Props = {
export function SearchBar({ className }: Props) { export function SearchBar({ className }: Props) {
const [onSelected, setOnSelected] = useState(""); // Selected item from response list const [onSelected, setOnSelected] = useState(""); // Selected item from response list
const { t, i18n } = useTranslation();
const searchResolver = (item: any) => { const searchResolver = (item: any) => {
setOnSelected(item.caption); setOnSelected(item.caption);
@ -31,6 +34,7 @@ export function SearchBar({ className }: Props) {
onSelected={searchResolver} onSelected={searchResolver}
className="w-full" className="w-full"
inGroup={true} inGroup={true}
placeHolder={t("mainPage.search") + "..."}
/> />
</div> </div>
</div> </div>

View File

@ -11,3 +11,7 @@ export const handleScrollTo = (e: React.MouseEvent<HTMLAnchorElement>) => {
export function capitalization (str: string) { export function capitalization (str: string) {
return str.substring(0,1).toUpperCase() + str.substring(1); return str.substring(0,1).toUpperCase() + str.substring(1);
} }
export function formatNumber(num: number) {
return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1 ');
}

View File

@ -16,6 +16,7 @@ import AccountSettings from "pages/Information/AccountSettings";
import { store } from "store/store"; import { store } from "store/store";
import { Provider } from "react-redux"; import { Provider } from "react-redux";
import { SearchResultsPage } from "pages/SearchResultsPage"; import { SearchResultsPage } from "pages/SearchResultsPage";
import AnArticle from "components/fetchAnArticle/AnArticle";
const rootElement = document.getElementById("root"); const rootElement = document.getElementById("root");
if (!rootElement) throw new Error("Failed to find the root element"); if (!rootElement) throw new Error("Failed to find the root element");
@ -32,6 +33,7 @@ root.render(
<Route path="/terms-of-use" element={<TermsOfUse />} /> <Route path="/terms-of-use" element={<TermsOfUse />} />
<Route path="/privacy-policy" element={<PrivacyPolicy />} /> <Route path="/privacy-policy" element={<PrivacyPolicy />} />
<Route path="/cookies-policy" element={<CookiesPolicy />} /> <Route path="/cookies-policy" element={<CookiesPolicy />} />
<Route path="/article/:id" element={<AnArticle />} />
<Route path="/account"> <Route path="/account">
<Route path="settings" element={<AccountSettings />} /> <Route path="settings" element={<AccountSettings />} />
</Route> </Route>

View File

@ -18,11 +18,11 @@ export const languages: Record<Langs, Lang> = {
}, },
}; };
export const popularLangKeys = ["ru", "en"]; export const popularLangKeys = ["ru", "en"];
const fallbackLng: Langs = "en"; const fallbackLng: Langs = "ru";
i18n i18n
.use(Backend) .use(Backend)
.use(LanguageDetector) // .use(LanguageDetector)
.use(initReactI18next) .use(initReactI18next)
.init({ .init({
debug: process.env.NODE_ENV === "development" ? true : false, debug: process.env.NODE_ENV === "development" ? true : false,

View File

@ -20,7 +20,6 @@ export default function MainPage({ className }: Props) {
<FeaturedArticlesCategories></FeaturedArticlesCategories> <FeaturedArticlesCategories></FeaturedArticlesCategories>
<FeaturedArticlesCards></FeaturedArticlesCards> <FeaturedArticlesCards></FeaturedArticlesCards>
<FeaturedAuthorsCards></FeaturedAuthorsCards> <FeaturedAuthorsCards></FeaturedAuthorsCards>
<BottomBarAcceptCookies></BottomBarAcceptCookies>
</BaseLayout> </BaseLayout>
</div> </div>
); );

View File

@ -19,7 +19,7 @@ export const SearchResultsPage = () => {
<SearchResultSection /> <SearchResultSection />
</ColumnLayout.Main> </ColumnLayout.Main>
<ColumnLayout.Right> <ColumnLayout.Right>
<div className="h-98 bg-blue-200 w-[300px]">right bar</div> <div className="w-[300px]"></div>
</ColumnLayout.Right> </ColumnLayout.Right>
</ColumnLayout> </ColumnLayout>
</BaseLayout> </BaseLayout>