Merge branch 'feature/add-filters' of http://85.143.176.51:3000/free-land/front-end into feature/add-filters
This commit is contained in:
commit
969749c0c0
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"serv": {
|
"serv": {
|
||||||
"goHome": "Home",
|
"goHome": "Home page",
|
||||||
"noSuchPath": "We don't have this page"
|
"noSuchPath": "We don't have such a page"
|
||||||
},
|
},
|
||||||
"sidemenu": {
|
"sidemenu": {
|
||||||
"dashboard": "Dashboard",
|
"dashboard": "Dashboard",
|
||||||
@ -19,45 +19,110 @@
|
|||||||
"hellousr": "Hello, {{username}}",
|
"hellousr": "Hello, {{username}}",
|
||||||
"edit": "Edit",
|
"edit": "Edit",
|
||||||
"language": "Language",
|
"language": "Language",
|
||||||
"selectLanguage": "Select language",
|
"selectLanguage": "Select a language",
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"account": {
|
"account": {
|
||||||
"info": "Personal information",
|
"info": "Personal Information",
|
||||||
"mail": "Mail",
|
"mail": "Mail",
|
||||||
"connect": "Add account",
|
"connect": "Add Account",
|
||||||
"connectedAccounts_one": "Connected account",
|
"connectedAccounts_one": "Linked Account",
|
||||||
"connectedAccounts_other": "Connected accounts",
|
"connectedAccounts_other": "Linked Accounts",
|
||||||
"settings": "Account settings"
|
"settings": "Account Settings"
|
||||||
},
|
},
|
||||||
"security": {
|
"security": {
|
||||||
"password": {
|
"password": {
|
||||||
"caption": "Password",
|
"caption": "Password",
|
||||||
"twoFactor": "Two factor authentication (2FA)",
|
"twoFactor": "Two-factor authentication (2FA)",
|
||||||
"description": "Keep your account secure by enabling 2FA via SMS or using a temporary one-time passcode (TOTP) from an authenticator app."
|
"description": "Protect your account by enabling 2FA via SMS or using a temporary one-time password (OTP) from the authentication app."
|
||||||
},
|
},
|
||||||
"activity": {
|
"activity": {
|
||||||
"caption": "Device activity"
|
"caption": "Device activity"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"label": "Search for something.."
|
"label": "We will find something.."
|
||||||
},
|
},
|
||||||
"subscriptions": {
|
"subscriptions": {
|
||||||
"subscribed": "Service have been connected"
|
"subscribed": "The service is attached to the account"
|
||||||
},
|
},
|
||||||
"viewHistory": "View history",
|
"viewHistory": "View history",
|
||||||
"logOutEverywhere": "log out from all devices",
|
"logOutEverywhere": "Log out from all devices",
|
||||||
"back": "Back",
|
"back": "Back",
|
||||||
"logOut": "Log out",
|
"logOut": "Exit",
|
||||||
"failures": {
|
"failures": {
|
||||||
"subscriptions": {
|
"subscriptions": {
|
||||||
"failure": "Failed to connect service",
|
"failure": "Failed to attach the service to your account",
|
||||||
"exists": "Service have already been connected",
|
"exists": "The service was already attached to your account earlier",
|
||||||
"confirmation": "Invalid confirmation information provided"
|
"confirmation": "Invalid password"
|
||||||
},
|
},
|
||||||
"services": {
|
"services": {
|
||||||
"fork": "Failed to authenticate in service"
|
"fork": "Failed to perform authorization in the service"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"articlePage": {
|
||||||
|
"abstract": "Abstract",
|
||||||
|
"keywords": "Keywords"
|
||||||
|
},
|
||||||
|
"navbar": {
|
||||||
|
"createNew": "Create an article",
|
||||||
|
"about": {
|
||||||
|
"navTitle": "About the project",
|
||||||
|
"aboutProject": "About Scipaper",
|
||||||
|
"contacts": "Contacts",
|
||||||
|
"help": "Help"
|
||||||
|
},
|
||||||
|
"library": {
|
||||||
|
"navTitle": "My library",
|
||||||
|
"publications": "Publications",
|
||||||
|
"favorites": "Favorites",
|
||||||
|
"collections": "Collections",
|
||||||
|
"recentViewed": "History"
|
||||||
|
},
|
||||||
|
"auth": {
|
||||||
|
"signIn": "Sign In",
|
||||||
|
"signUp": "Sign Up"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"footer": {
|
||||||
|
"accountSettings": "Account Settings",
|
||||||
|
"about": "About Scipaper",
|
||||||
|
"help": "Help",
|
||||||
|
"contactUs": "Contacts",
|
||||||
|
"allRightsReserved": "All rights reserved",
|
||||||
|
"termsOfUse": "Terms of Use",
|
||||||
|
"privacyPolicy": "Privacy Policy",
|
||||||
|
"coockiesPolicy": "coockies Usage Policy",
|
||||||
|
"supportedBy": "Created"
|
||||||
|
},
|
||||||
|
"mainPage": {
|
||||||
|
"title": "Scientific Library with free access",
|
||||||
|
"search": "Search",
|
||||||
|
"article_one": "Articles",
|
||||||
|
"article_few": "Articles",
|
||||||
|
"article_many": "Articles",
|
||||||
|
"advancedSearch": "Advanced search",
|
||||||
|
"featuredArticles": {
|
||||||
|
"title": "Popular articles",
|
||||||
|
"descriptionPart1": "Choose the one you are interested in",
|
||||||
|
"descriptionPart2": "Scientific category",
|
||||||
|
"categories": {
|
||||||
|
"Medical": "Medical",
|
||||||
|
"TechnicsAndTechlonogies": "Technics and Technology",
|
||||||
|
"Fundamental": "Fundamental",
|
||||||
|
"Humanitarian": "Humanitarian",
|
||||||
|
"Agricultural": "Agricultural",
|
||||||
|
"Social": "Social"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"featuredAuthors": "Popular authors",
|
||||||
|
"more": "More",
|
||||||
|
"showAll": "Show all"
|
||||||
|
},
|
||||||
|
"searchResults": {
|
||||||
|
"title": "Search results",
|
||||||
|
"totalResults":"Total results",
|
||||||
|
"nothingFound": "Nothing found"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -12,6 +12,7 @@ import {
|
|||||||
} from "components/icons";
|
} from "components/icons";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { Transition } from "@headlessui/react";
|
import { Transition } from "@headlessui/react";
|
||||||
|
import Link from "components/typography/Link";
|
||||||
|
|
||||||
const interactionButtonsStore = [
|
const interactionButtonsStore = [
|
||||||
{
|
{
|
||||||
@ -46,6 +47,7 @@ type ArticleButtonProps = {
|
|||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
emphasis?: "high" | "low";
|
emphasis?: "high" | "low";
|
||||||
|
articleID?: string,
|
||||||
} & Omit<React.ComponentPropsWithoutRef<"button">, "">;
|
} & Omit<React.ComponentPropsWithoutRef<"button">, "">;
|
||||||
|
|
||||||
export function ArticleInteractionButtons({
|
export function ArticleInteractionButtons({
|
||||||
@ -53,6 +55,7 @@ export function ArticleInteractionButtons({
|
|||||||
children,
|
children,
|
||||||
openAbstract = () => { },
|
openAbstract = () => { },
|
||||||
className,
|
className,
|
||||||
|
articleID,
|
||||||
emphasis = "high", //to change displaying of component
|
emphasis = "high", //to change displaying of component
|
||||||
...props
|
...props
|
||||||
}: ArticleButtonProps) {
|
}: ArticleButtonProps) {
|
||||||
@ -70,9 +73,22 @@ export function ArticleInteractionButtons({
|
|||||||
</Button.Icon>
|
</Button.Icon>
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
|
||||||
const fileInteractionButtons = interactionButtonsStore.map((button) => {
|
const fileInteractionButtons = interactionButtonsStore.map((button) => {
|
||||||
return (
|
return (
|
||||||
|
button.title === 'Read file' ?
|
||||||
|
<Link
|
||||||
|
to={`/article/content/${articleID}`}>
|
||||||
|
<Button
|
||||||
|
emphasis={button.buttonEmphasis === "high" ? "high" : "low"}
|
||||||
|
className="h-max px-2 mr-2"
|
||||||
|
>
|
||||||
|
<Button.Icon>
|
||||||
|
{React.cloneElement(button.icon, { className: button.iconClassName })}
|
||||||
|
</Button.Icon>
|
||||||
|
{emphasis === "high" ? <Typography>{button.title}</Typography> : null}
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
:
|
||||||
<Button
|
<Button
|
||||||
emphasis={button.buttonEmphasis === "high" ? "high" : "low"}
|
emphasis={button.buttonEmphasis === "high" ? "high" : "low"}
|
||||||
className="h-max px-2 mr-2"
|
className="h-max px-2 mr-2"
|
||||||
|
@ -37,7 +37,7 @@ export const ArticleSearchResult = ({ searchItem }: Props) => {
|
|||||||
<Article.SubscriptionsButtons />
|
<Article.SubscriptionsButtons />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Article.Title linkTo={`/article/${searchItem.id}`} className="text-2xl">
|
<Article.Title linkTo={`/article/info/${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">
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { joinClassnames } from "core/helpers";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Footer } from "./parts/Footer";
|
import { Footer } from "./parts/Footer";
|
||||||
import Header from "./parts/Header";
|
import Header from "./parts/Header";
|
||||||
@ -10,10 +11,10 @@ type Props = {
|
|||||||
|
|
||||||
function BaseLayout({ header, footer, children, className }: Props) {
|
function BaseLayout({ header, footer, children, className }: Props) {
|
||||||
return (
|
return (
|
||||||
<div className={className}>
|
<div className={joinClassnames(className, 'flex min-h-screen flex-col justify-between')}>
|
||||||
<Header />
|
<Header />
|
||||||
|
|
||||||
<main>{children}</main>
|
<main className="flex-1">{children}</main>
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
|
@ -98,10 +98,10 @@ 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()
|
const [t, i18next] = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="slider-wrapper articles">
|
<div className="slider-wrapper articles px-8">
|
||||||
<div className="flex justify-end gap-2 my-2">
|
<div className="flex justify-end gap-2 my-2">
|
||||||
<div
|
<div
|
||||||
className="prev inline-flex justify-center items-center
|
className="prev inline-flex justify-center items-center
|
||||||
|
@ -75,10 +75,12 @@ export default function FeaturedAuthorsCards(): JSX.Element {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{/* The Title of Featured Authors section */}
|
{/* The Title of Featured Authors section */}
|
||||||
<Heading className="text-center my-8 text-3xl font-semibold">{t("mainPage.featuredAuthors")}</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 px-8">
|
||||||
<Swiper
|
<Swiper
|
||||||
slidesPerView={1.25}
|
slidesPerView={1.25}
|
||||||
slidesPerGroup={1}
|
slidesPerGroup={1}
|
||||||
@ -133,7 +135,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="*">
|
||||||
{t('mainPage.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>
|
||||||
|
@ -33,7 +33,7 @@ const AnArticle = () => {
|
|||||||
<AskeletonArticle />
|
<AskeletonArticle />
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<ArticlePart.Article.Breadcumbs>
|
<ArticlePart.Article.Breadcumbs className="py-4">
|
||||||
{article?.topic}
|
{article?.topic}
|
||||||
</ArticlePart.Article.Breadcumbs>
|
</ArticlePart.Article.Breadcumbs>
|
||||||
<div className="flex flex-col gap-4 pb-4">
|
<div className="flex flex-col gap-4 pb-4">
|
||||||
@ -46,28 +46,24 @@ const AnArticle = () => {
|
|||||||
<hr></hr>
|
<hr></hr>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ArticlePart.Article.InteractionButtons emphasis="high" />
|
<ArticlePart.Article.InteractionButtons
|
||||||
|
emphasis="high"
|
||||||
|
articleID={article?.id}
|
||||||
|
/>
|
||||||
{article?.tags && (
|
{article?.tags && (
|
||||||
<div className="keywords my-10 flex flex-col gap-2">
|
<div className="keywords my-10 flex flex-col gap-2">
|
||||||
<Typography
|
<Typography className="text-2xl" fontWeightVariant="semibold">
|
||||||
className="text-2xl"
|
{t("articlePage.keywords")}
|
||||||
fontWeightVariant="semibold"
|
|
||||||
>
|
|
||||||
{t('articlePage.keywords')}
|
|
||||||
</Typography>
|
</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}
|
||||||
</ArticlePart.Article.Keywords>
|
</ArticlePart.Article.Keywords>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="abstract my-10 flex flex-col gap-2">
|
<div className="abstract my-10 flex flex-col gap-2">
|
||||||
<Typography
|
<Typography className="text-2xl" fontWeightVariant="semibold">
|
||||||
className="text-2xl"
|
{t("articlePage.abstract")}
|
||||||
fontWeightVariant="semibold"
|
|
||||||
>
|
|
||||||
{t('articlePage.abstract')}
|
|
||||||
</Typography>
|
</Typography>
|
||||||
<ArticlePart.Article.Description>
|
<ArticlePart.Article.Description>
|
||||||
{article?.summary !== undefined ? (
|
{article?.summary !== undefined ? (
|
||||||
|
@ -27,7 +27,7 @@ const AnArticleBody = () => {
|
|||||||
<Container variant="straight">
|
<Container variant="straight">
|
||||||
{shouldShowLoading ? (
|
{shouldShowLoading ? (
|
||||||
<>
|
<>
|
||||||
<Skeleton count={1} />
|
<Skeleton count={1} className="my-4" />
|
||||||
<div className="gap-4 py-12 px-20">
|
<div className="gap-4 py-12 px-20">
|
||||||
<Skeleton
|
<Skeleton
|
||||||
count={1}
|
count={1}
|
||||||
@ -39,7 +39,7 @@ const AnArticleBody = () => {
|
|||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<ArticlePart.Article.Breadcumbs>
|
<ArticlePart.Article.Breadcumbs className="py-4">
|
||||||
{article?.topic}
|
{article?.topic}
|
||||||
</ArticlePart.Article.Breadcumbs>
|
</ArticlePart.Article.Breadcumbs>
|
||||||
<div className="gap-4 py-12 px-20">
|
<div className="gap-4 py-12 px-20">
|
||||||
|
@ -3,7 +3,7 @@ import "react-loading-skeleton/dist/skeleton.css";
|
|||||||
const AskeletonArticle = () => {
|
const AskeletonArticle = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Skeleton count={1} />
|
<Skeleton count={1} className="my-4" />
|
||||||
<div className="flex flex-col gap-4 pb-4">
|
<div className="flex flex-col gap-4 pb-4">
|
||||||
<Skeleton count={1} containerClassName="title w-3/4 text-2xl" />
|
<Skeleton count={1} containerClassName="title w-3/4 text-2xl" />
|
||||||
<Skeleton count={1} containerClassName="authors w-1/4" />
|
<Skeleton count={1} containerClassName="authors w-1/4" />
|
||||||
|
@ -51,6 +51,7 @@ export default function Link({
|
|||||||
: style
|
: style
|
||||||
}
|
}
|
||||||
aria-disabled={disabled}
|
aria-disabled={disabled}
|
||||||
|
className="flex items-center"
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
@ -8,10 +8,17 @@ export const handleScrollTo = (e: React.MouseEvent<HTMLAnchorElement>) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export function capitalization (str: string) {
|
export function capitalization(str: string): string {
|
||||||
return str.substring(0, 1).toUpperCase() + str.substring(1);
|
return str.substring(0, 1).toUpperCase() + str.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatNumber(num: number) {
|
export function formatNumber(num: number): string {
|
||||||
return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1 ');
|
return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1 ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function joinClassnames(first?: string, second?: string): string {
|
||||||
|
return [
|
||||||
|
first ?? '',
|
||||||
|
second ?? '',
|
||||||
|
].join('');
|
||||||
|
}
|
@ -17,6 +17,8 @@ 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";
|
import AnArticle from "components/fetchAnArticle/AnArticle";
|
||||||
|
import NotFound from "components/fetchAnArticle/NotFound";
|
||||||
|
import AnArticleBody from "components/fetchAnArticle/AnArticleBody";
|
||||||
|
|
||||||
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");
|
||||||
@ -33,11 +35,15 @@ 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="/article">
|
||||||
|
<Route path="info/:id" element={<AnArticle />} />
|
||||||
|
<Route path="content/:id" element={<AnArticleBody />} />
|
||||||
|
</Route>
|
||||||
<Route path="/account">
|
<Route path="/account">
|
||||||
<Route path="settings" element={<AccountSettings />} />
|
<Route path="settings" element={<AccountSettings />} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/search-results" element={<SearchResultsPage />}></Route>
|
<Route path="/search-results" element={<SearchResultsPage />} />
|
||||||
|
<Route path="/*" element={<NotFound />}></Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
|
@ -14,7 +14,7 @@ export const SearchResultsPage = () => {
|
|||||||
<SearchSection />
|
<SearchSection />
|
||||||
<ColumnLayout>
|
<ColumnLayout>
|
||||||
<ColumnLayout.Left>
|
<ColumnLayout.Left>
|
||||||
<div className="w-[300px] border rounded my-5"><Fiter/></div>
|
<div className="h-98 w-[300px]"></div>
|
||||||
</ColumnLayout.Left>
|
</ColumnLayout.Left>
|
||||||
<ColumnLayout.Main>
|
<ColumnLayout.Main>
|
||||||
<SearchResultSection />
|
<SearchResultSection />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user