Merge branch 'myCheck/working-develop' into feature/triple-column-layout

This commit is contained in:
Maximus 2022-08-20 16:43:36 +03:00
commit 9376f9db09
12 changed files with 240 additions and 502 deletions

16
src/App.tsx Normal file
View File

@ -0,0 +1,16 @@
/* -------------------------------------------------------------------------- */
/* Libraries */
/* -------------------------------------------------------------------------- */
import React from "react";
/* -------------------------------------------------------------------------- */
/* Application root component */
/* -------------------------------------------------------------------------- */
/**
* Application root component
* @return {JSX.Element}
*/
function App() {
return <div>Hello world!</div>;
}
export default App;

View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -1,5 +1,5 @@
import React from "react";
// import { Footer } from "./parts/Footer";
import { Footer } from "./parts/Footer";
import Header from "./parts/Header";
type Props = {
header?: React.ReactElement;

View File

@ -1,115 +0,0 @@
/* -------------------------------------------------------------------------- */
/* Imports */
/* -------------------------------------------------------------------------- */
import React, { Fragment } from "react";
import { Menu, Transition } from "@headlessui/react";
import { PropsPartion } from "./ContextMenuItem";
import classNames from "classnames";
import { ReactComponent as SelectIcon } from "assets/svg/select-arrow.svg";
type ChildType = React.ReactElement<any & PropsPartion[]>;
type ChildrenType = ChildType[] | ChildType;
/* -------------------------------------------------------------------------- */
/* Component props */
/* -------------------------------------------------------------------------- */
type MenuProps = {
emphasis?: "high" | "low";
disabled?: boolean;
className?: string | undefined;
button: React.ReactNode;
children: ChildrenType;
};
/* -------------------------------------------------------------------------- */
/* Styles */
/* -------------------------------------------------------------------------- */
const MenuButtonStyle = `
inline-flex
justify-center w-full
cursor-default
rounded
border border-gray-100
outline-8
py-2
px-2
text-base`;
const MenuItemStyle = `
absolute
left-0
mt-2 w-60
origin-top-left
rounded
shadow-lg
focus:outline-none
py-2 px-4 sm:text-sm`;
/* -------------------------------------------------------------------------- */
/* Component implementation */
/* -------------------------------------------------------------------------- */
/**
* Use width ContextMenuAction.tsx , for example:
* <ContextMenu button="MyButton" emphasis="low/high">
* <ContextMenuAction
* caption="First Menu"
* icon={icon}
* action={() => alert('click')}
* ></ContextMenuAction>
* ...
* </ContextMenu>
*/
export default function ContextMenu({
button,
children,
className,
emphasis = "low",
}: MenuProps) {
return (
<Menu as="div" className="relative inline-block text-right">
{({ open }) => (
<>
<Menu.Button
className={classNames([
`${MenuButtonStyle}`,
{
"hover:bg-gray-100 font-bold uppercase": emphasis === "high",
},
className,
])}
>
{button}
<SelectIcon
className={`${
open ? "rotate-180 transform" : "font-normal"
} my-2 mx-3 h-2 w-3 flex-center`}
aria-hidden="true"
/>
</Menu.Button>
<Transition
as={Fragment}
show={open}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items
static
className={classNames([
className,
`${MenuItemStyle}`,
{ "ml-2": emphasis === "high" },
])}
>
{children}
</Menu.Items>
</Transition>
</>
)}
</Menu>
);
}

View File

@ -1,32 +0,0 @@
import classNames from "classnames";
import React from "react";
type Props = {
action: Function;
caption: string;
disabled?: boolean;
icon?: React.ReactNode;
className?: string | undefined;
};
export default function ContextMenuAction({
action,
caption,
disabled,
icon,
className,
}: Props) {
return (
<a
href="#"
onClick={(e) => action(e)}
className={classNames([
"group flex px-2 rounded items-center text-base hover:bg-gray-100",
className,
])}
>
{icon && <div className="mr-2 h-5 w-5">{icon}</div>}
<span className="px-2 py-2">{caption}</span>
</a>
);
}

View File

@ -1,163 +0,0 @@
import classNames from "classnames";
import { useState } from "react";
/* -------------------------------------------------------------------------- */
/* Components */
/* -------------------------------------------------------------------------- */
import ContextMenuAction from "./ContextMenuAction";
import ContextMenu from "./ContextMenu";
import Logofreeland from "./Logofreeland";
import { Button } from "./Button/Button";
import Avatar from "./Avatar";
import Navbar from "./Navbar";
import Bell from "./Bell";
import Logo from "./Logo";
import Link from "./Link";
/* -------------------------------------------------------------------------- */
/* Icons */
/* -------------------------------------------------------------------------- */
import { ReactComponent as SVGFavoriteOutlined } from "assets/svg/favorite-outlined.svg";
import { ReactComponent as SVGFolder } from "assets/svg/folder.svg";
import { ReactComponent as SVGFile } from "assets/svg/file.svg";
import { ReactComponent as SVGEye } from "assets/svg/eye.svg";
const Header = () => {
const [authenticated, setAuthenticated] = useState(false);
const onClick = () => setAuthenticated(true);
/* -------------------------------------------------------------------------- */
/* Implement Header Component */
/* -------------------------------------------------------------------------- */
return (
<header
className="header flex justify-between items-center box-border w-full
border border-gray-75
h-16
px-4
gap-5
md:gap-20
lg:gap-40 lg:px-8
xl:gap-60 xl:px-16"
>
{/* Logo and Menu */}
<div className="flex gap-8 xl:gap-x-16">
{/* Logo - start - className="w-7 sm:w-10 " /> */}
<a className="Logo flex items-center gap-1 sm:gap-2 " href="/">
<Logo
className={classNames(authenticated ? "w-10" : "w-7 sm:w-10")}
/>
<Logofreeland
className={classNames(authenticated ? "w-28" : "w-20 sm:w-28")}
/>
</a>
{/* Logo - end - */}
{/* Menu( Create new - My library - About ) Start */}
<div
className="hidden lg:flex items-center
gap-2"
>
{/* Link Create now - start - */}
<Link className="text-blue-500 px-4 font-bold uppercase" href="#">
Create new
</Link>
{/* Link Create now - end - */}
{/* Dropdown Menu My library - start - */}
<ContextMenu
emphasis="high"
button="My library"
className="border-none uppercase"
>
<ContextMenuAction
caption="My Publications"
action={() => console.log("My publications")}
icon={<SVGFile className="stroke-black " />}
></ContextMenuAction>
<ContextMenuAction
caption="My Favorites"
action={() => console.log("My Favorites")}
icon={<SVGFavoriteOutlined className="stroke-black" />}
></ContextMenuAction>
<ContextMenuAction
caption="My Collections"
action={() => console.log("My Collections")}
icon={<SVGFolder className="stroke-black fill-black" />}
></ContextMenuAction>
<ContextMenuAction
caption="Recent Viewed"
action={() => console.log("Recent Viewed")}
icon={<SVGEye className="stroke-black " />}
></ContextMenuAction>
</ContextMenu>
{/* Dropdown Menu My library - End - */}
{/* Dropdown Menu About - start - */}
<ContextMenu
emphasis="high"
button="About"
className="border-none uppercase"
>
<ContextMenuAction
caption="About Freeland"
action={() => console.log("About Freeland")}
></ContextMenuAction>
<ContextMenuAction
caption="Contact Us"
action={() => console.log("Contact Us")}
></ContextMenuAction>
<ContextMenuAction
caption="Help"
action={() => console.log("Help")}
></ContextMenuAction>
</ContextMenu>
{/* Dropdown Menu About - End - */}
</div>
{/* Menu( Create new - My library - About ) End */}
</div>
{/* Sign in - Sign up - Notification - Avatar - Burger */}
<div className="flex items-center font-bold text-sm gap-1 md:gap-2 ">
{!authenticated
? [
<Button
emphasis="low"
onClick={onClick}
className="text-xs sm:px-4 sm:text-sm "
>
Sign in
</Button>,
<Button
emphasis="medium"
className="hidden md:flex"
onClick={onClick}
>
Sign up
</Button>,
]
: [
<Button emphasis="low">
<Button.Icon>
<Bell className="h-6 w-6" />
</Button.Icon>
</Button>,
<Button emphasis="low" className="hidden lg:flex">
<Button.Icon>
<Avatar className="bg-[rgb(255,122,69)] text-white">K</Avatar>
</Button.Icon>
</Button>,
]}
{/* Burger component will be shown for the small screens */}
<Navbar className="block lg:hidden" />
</div>
</header>
);
};
export default Header;

View File

@ -1,27 +0,0 @@
import React from 'react';
import {ReactComponent as SVGLogotype} from 'assets/svg/logotype.svg';
import { Link } from 'react-router-dom';
type Props = {
name?: string;
}
/**
* Horizontal variant of logotype component
* @param {string} name Name of service to attach to logotype
* @return {React.ReactNode}
*/
export default function Logotype({name}: Props): JSX.Element {
return (
<div className="inline-flex flex-row flex-nowrap items-center">
<div className="flex-none">
<Link to="/">
<SVGLogotype className="w-8 h-8 mr-2" />
</Link>
</div>
<div className="flex-initial text-2xl font-bold">
{name ?? ''} {process.env.REACT_APP_CMS_APP_NAME?.toLowerCase()}
</div>
</div>
);
}

View File

@ -5,8 +5,8 @@ import classNames from "classnames";
/* -------------------------------------------------------------------------- */
/* Components */
/* -------------------------------------------------------------------------- */
import ContextMenuAction from "./ContextMenuAction";
import ContextMenu from "./ContextMenu";
import ContextMenuAction from "./drop-down-menu/ContextMenuAction";
import ContextMenu from "./drop-down-menu/ContextMenu";
import { Button } from "./Button/Button";
/* -------------------------------------------------------------------------- */

View File

@ -5,7 +5,7 @@ import React, { Fragment } from "react";
import { Menu, Transition } from "@headlessui/react";
import { PropsPartion } from "./ContextMenuItem";
import classNames from "classnames";
import { ReactComponent as SelectIcon } from "assets/svg/select-arrow.svg";
import { SVGCaretDown } from "components/icons";
type ChildType = React.ReactElement<any & PropsPartion[]>;
type ChildrenType = ChildType[] | ChildType;
@ -25,13 +25,13 @@ type MenuProps = {
/* -------------------------------------------------------------------------- */
const MenuButtonStyle = `
items-center
inline-flex
justify-center w-full
cursor-default
rounded
border border-gray-100
outline-8
bg-white
py-2
pl-4
pr-1
@ -43,7 +43,7 @@ left-0
mt-2 w-60
origin-top-left
rounded
bg-white
bg-white
shadow-lg
focus:outline-none
py-2 px-4 sm:text-sm`;
@ -51,17 +51,17 @@ py-2 px-4 sm:text-sm`;
/* -------------------------------------------------------------------------- */
/* Component implementation */
/* -------------------------------------------------------------------------- */
/**
* Use width ContextMenuAction.tsx , for example:
* <ContextMenu button="MyButton" emphasis="low/high">
* <ContextMenuAction
* caption="First Menu"
* icon={icon}
* action={() => alert('click')}
* ></ContextMenuAction>
* ...
* </ContextMenu>
*/
/**
* Use width ContextMenuAction.tsx , for example:
* <ContextMenu button="MyButton" emphasis="low/high">
* <ContextMenuAction
* caption="First Menu"
* icon={icon}
* action={() => alert('click')}
* ></ContextMenuAction>
* ...
* </ContextMenu>
*/
export default function ContextMenu({
button,
children,
@ -69,48 +69,50 @@ export default function ContextMenu({
emphasis = "low",
}: MenuProps) {
return (
<Menu as="div" className="relative inline-block text-right">
{({ open }) => (
<>
<Menu.Button
<Menu as="div" className="relative inline-block text-right">
{({ open }) => (
<>
<Menu.Button
className={classNames([
`${MenuButtonStyle}`,
{
"hover:bg-gray-100 font-bold uppercase": emphasis === "high",
},
className,
])}
>
{button}
<SVGCaretDown
className={`${
open ? "rotate-180 transform" : "font-normal"
} my-2 mx-3 w-4 flex-center fill-gray-900 stroke-gray-900`}
aria-hidden="true"
/>
</Menu.Button>
<Transition
as={Fragment}
show={open}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items
static
className={classNames([
`${MenuButtonStyle}`,
{ "bg-gray-100 font-bold uppercase": emphasis === "high" },
className,
`${MenuItemStyle}`,
{ "ml-2": emphasis === "high" },
])}
>
{button}
<SelectIcon
className={`${
open ? "rotate-180 transform" : "font-normal"
} my-2 mx-3 h-2 w-3 flex-center`}
aria-hidden="true"
/>
</Menu.Button>
<Transition
as={Fragment}
show={open}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items
static
className={classNames([
className,
`${MenuItemStyle}`,
{ "ml-2": emphasis === "high" },
])}
>
{children}
</Menu.Items>
</Transition>
</>
)}
</Menu>
{children}
</Menu.Items>
</Transition>
</>
)}
</Menu>
);
}

View File

@ -1,7 +1,6 @@
import classNames from "classnames";
import React from "react";
type Props = {
action: Function;
caption: string;
@ -18,19 +17,16 @@ export default function ContextMenuAction({
className,
}: Props) {
return (
<button
<a
href="#"
onClick={(e) => action(e)}
disabled={disabled}
className={classNames([
"group flex items-center text-base",
{ "opacity-50": disabled, "cursor-default": !disabled },
"group flex px-2 rounded items-center text-base hover:bg-gray-100",
className,
])}
>
{icon && <div className="mr-2 h-5 w-5">{icon}</div>}
<span className="px-2 py-2">{caption}</span>
</button>
</a>
);
}

View File

@ -34,7 +34,7 @@ export { ReactComponent as SVGFilter } from "assets/svg/filter.svg";
export { ReactComponent as SVGFlag } from "assets/svg/flag.svg";
export { ReactComponent as SVGFolder } from "assets/svg/folder.svg";
export { ReactComponent as SVGFormula } from "assets/svg/formula.svg";
export { ReactComponent as SVGFundomental } from "assets/svg/fundomental.svg";
export { ReactComponent as SVGFundamental } from "assets/svg/fundamental.svg";
export { ReactComponent as SVGGrid } from "assets/svg/grid.svg";
export { ReactComponent as SVGHamburger } from "assets/svg/hamburger.svg";
export { ReactComponent as SVGHelp } from "assets/svg/help.svg";

View File

@ -1,113 +1,174 @@
/* -------------------------------------------------------------------------- */
/* Libs */
/* -------------------------------------------------------------------------- */
import React, { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import classNames from "classnames";
import { useState } from "react";
/* -------------------------------------------------------------------------- */
/* Components */
/* -------------------------------------------------------------------------- */
import ContextMenu from "components/containers/contextmenu/ContextMenu";
import Logotype from "components/Logotype";
import Avatar from "components/containers/Avatar";
import ContextMenuAction from "components/containers/contextmenu/ContextMenuAction";
/* -------------------------------------------------------------------------- */
/* SVG */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Hooks */
/* -------------------------------------------------------------------------- */
import { useUserStore } from "user/data/userSlice";
import { useUserViewModel } from "user/controller/userViewModel";
import { useUIStore } from "ui/data/uiSlice";
import { useUIViewModel } from "ui/controller/uiViewModel";
import { useTranslation } from "react-i18next";
import ServicesNavigationContext from "services/views/ServicesNavigationContext";
import { useAuthStore } from "auth/data/authSlice";
import { useAuthViewModel } from "auth/controller/useAuthViewModel";
import ContextMenuAction from "../drop-down-menu/ContextMenuAction";
import ContextMenu from "../drop-down-menu/ContextMenu";
import Logofreeland from "../Logofreeland";
import { Button } from "../Button/Button";
import Avatar from "../Avatar";
import Navbar from "../Navbar";
import Logo from "../Logo";
import { RouterLink } from "components/typography/RouterLink";
/* -------------------------------------------------------------------------- */
/* Main application header */
/* Icons */
/* -------------------------------------------------------------------------- */
type Props = {
title?: string;
}
/**
* Main application header
* @return {JSX.Element}
*/
export default function Header({title}: Props) {
import {
SVGBellNotification,
SVGBell,
SVGFavoriteOutlined,
SVGFolder,
SVGFile,
SVGEye,
} from "components/icons";
const {t} = useTranslation();
const userStore = useUserStore();
const uiStore = useUIStore();
const authStore = useAuthStore();
const {signOut} = useAuthViewModel(authStore);
const { user, isLoading, getUser } = useUserViewModel(userStore);
const { showSearchbar } = useUIViewModel(uiStore);
const Header = () => {
const [authenticated, setAuthenticated] = useState(false);
const onClick = () => setAuthenticated(true);
const [notification, setNotification] = useState(false);
useEffect(() => {
getUser();
}, [getUser]);
const navigate = useNavigate();
/* -------------------------------------------------------------------------- */
/* Implement Header Component */
/* -------------------------------------------------------------------------- */
return (
<div
className="flex items-center flex-row
justify-between py-2.5 px-8 bg-gray-300/5 h-14"
<header
className="header flex justify-between items-center box-border w-full
border border-gray-75
h-16
px-4
gap-5
md:gap-20
lg:gap-40 lg:px-8
xl:gap-60 xl:px-16"
>
<div className="flex-none flex items-center space-x-3">
<ServicesNavigationContext />
<Logotype name={title} />
</div>
<div className="flex-none flex items-center space-x-3">
<ContextMenu
button={<Avatar className="p-2" />}
className="absolute w-full min-h-14 sm:w-80 -bottom-3
sm:top-auto sm:bottom-auto right-0
mt-5 z-10 sm:transform -translate-1/2
origin-top-center flex flex-col items-center justify-center !pt-8"
{/* Logo and Menu */}
<div className="flex gap-8 xl:gap-x-16">
{/* Logo - start - className="w-7 sm:w-10 " /> */}
<a className="Logo flex items-center gap-1 sm:gap-2 " href="/">
<Logo
className={classNames(authenticated ? "w-10" : "w-7 sm:w-10")}
/>
<Logofreeland
className={classNames(authenticated ? "w-28" : "w-20 sm:w-28")}
/>
</a>
{/* Logo - end - */}
{/* Menu( Create new - My library - About ) Start */}
<div
className="hidden lg:flex items-center
gap-2"
>
<Logotype name="techpal" />
<div className="w-full my-4 flex justify-center">
<Avatar width="27%" className="p-3.5" />
</div>
<div className="text-xl text-center font-bold leading-relaxed">
{isLoading
? " "
: t("hellousr", {
username: [user?.lastname, user?.firstname].join(" "),
})}
</div>
<div className="text-sm text-center text-gray-300 leading-relaxed mb-5">
{isLoading ? " " : user?.email}
</div>
<ContextMenuAction
action={() => {
navigate('/personal-information');
}}
disabled={isLoading}
className="group w-full py-2 -mx-4 px-4 hover:bg-gray-200/20 rounded-md hover:text-blue-400 transition-colors"
caption="Account settings"
/>
<ContextMenuAction
action={() => {
navigate("");
}}
disabled={isLoading}
className="group w-full py-2 -mx-4 px-4 hover:bg-gray-200/20 rounded-md hover:text-blue-400 transition-colors"
caption={t("account.connect")}
/>
<ContextMenuAction
action={signOut}
className="group w-full py-2 -mx-4 px-4 hover:bg-gray-200/20 rounded-md transition-colors"
caption={t('logOut')}
/>
</ContextMenu>
{/* Link Create now - start - */}
<RouterLink
className="text-blue-500 px-4 font-bold uppercase"
to="/create-new"
>
Create new
</RouterLink>
{/* Link Create now - end - */}
{/* Dropdown Menu My library - start - */}
<ContextMenu
emphasis="high"
button="My library"
className="border-none uppercase"
>
<ContextMenuAction
caption="My Publications"
action={() => console.log("My publications")}
icon={<SVGFile className="stroke-black " />}
></ContextMenuAction>
<ContextMenuAction
caption="My Favorites"
action={() => console.log("My Favorites")}
icon={<SVGFavoriteOutlined className="stroke-black" />}
></ContextMenuAction>
<ContextMenuAction
caption="My Collections"
action={() => console.log("My Collections")}
icon={<SVGFolder className="stroke-black fill-black" />}
></ContextMenuAction>
<ContextMenuAction
caption="Recent Viewed"
action={() => console.log("Recent Viewed")}
icon={<SVGEye className="stroke-black " />}
></ContextMenuAction>
</ContextMenu>
{/* Dropdown Menu My library - End - */}
{/* Dropdown Menu About - start - */}
<ContextMenu
emphasis="high"
button="About"
className="border-none uppercase"
>
<ContextMenuAction
caption="About Freeland"
action={() => console.log("About Freeland")}
></ContextMenuAction>
<ContextMenuAction
caption="Contact Us"
action={() => console.log("Contact Us")}
></ContextMenuAction>
<ContextMenuAction
caption="Help"
action={() => console.log("Help")}
></ContextMenuAction>
</ContextMenu>
{/* Dropdown Menu About - End - */}
</div>
{/* Menu( Create new - My library - About ) End */}
</div>
</div>
{/* Sign in - Sign up - Notification - Avatar - Burger */}
<div className="flex items-center font-bold text-sm gap-1 md:gap-2 ">
{!authenticated
? [
<Button
emphasis="low"
onClick={onClick}
className="text-xs sm:px-4 sm:text-sm "
>
Sign in
</Button>,
<Button
emphasis="medium"
className="hidden md:flex"
onClick={onClick}
>
Sign up
</Button>,
]
: [
<Button emphasis="low">
<Button.Icon>
{!notification ? (
<SVGBell className="h-6 w-6 fill-gray-900 stroke-gray-900" />
) : (
<SVGBellNotification className="h-6 w-6 fill-gray-900 stroke-gray-900" />
)}
</Button.Icon>
</Button>,
<Button emphasis="low" className="hidden lg:flex">
<Button.Icon>
<Avatar className="bg-[rgb(255,122,69)] text-white">K</Avatar>
</Button.Icon>
</Button>,
]}
{/* Burger component will be shown for the small screens */}
<Navbar className="block lg:hidden" />
</div>
</header>
);
}
};
export default Header;