Skip to content

Commit

Permalink
Add necessary UI components
Browse files Browse the repository at this point in the history
- Header
- Heading
- Container

Add useBasicLayout hook
Add ContentManagement view page with content query
Update login page with new cover image
  • Loading branch information
shreeyash07 committed Nov 21, 2024
1 parent 3bfb99b commit 361029c
Show file tree
Hide file tree
Showing 23 changed files with 2,524 additions and 2,091 deletions.
3,892 changes: 1,869 additions & 2,023 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/App/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import '@togglecorp/toggle-ui/build/index.css';

import {
useCallback,
useEffect,
Expand Down
Binary file added src/assets/loginCover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
90 changes: 90 additions & 0 deletions src/components/Container/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { _cs } from '@togglecorp/fujs';

import Header from '#components/Header';
import { type Props as HeadingProps } from '#components/Heading';

import styles from './styles.module.css';

interface Props {
actions?: React.ReactNode;
actionsContainerClassName?: string;
className?: string;
containerRef?: React.RefObject<HTMLDivElement>;
children?: React.ReactNode;
withHeaderBorder?: boolean,
showHeader?: boolean,
headerDescription?: string;
heading?: React.ReactNode;
headingClassName?: string;
headingContainerClassName?: string;
headingLevel?: HeadingProps['level'],
headingSectionClassName?: string;
icons?: React.ReactNode;
iconsContainerClassName?: string;
headingDescription?: React.ReactNode;
headingDescriptionContainerClassName?: string;
headerDescriptionContainerClassName?: string;
childrenContainerClassName?: string;
}

function Container(props: Props) {
const {
actions,
actionsContainerClassName,
className,
containerRef,
children,
withHeaderBorder = false,
showHeader,
headerDescription,
heading,
headingLevel,
headingSectionClassName,
headingClassName,
headingContainerClassName,
headingDescription,
headerDescriptionContainerClassName,
headingDescriptionContainerClassName,
icons,
childrenContainerClassName,
iconsContainerClassName,
} = props;

if (!children) {
return null;
}

return (
<div
ref={containerRef}
className={_cs(className, styles.container)}
>
{showHeader && (
<Header
icons={icons}
iconsContainerClassName={iconsContainerClassName}
actions={actions}
actionsContainerClassName={actionsContainerClassName}
heading={heading}
headingLevel={headingLevel}
headingClassName={headingClassName}
headingSectionClassName={headingSectionClassName}
headingContainerClassName={headingContainerClassName}
headingDescription={headingDescription}
headingDescriptionContainerClassName={headingDescriptionContainerClassName}
childrenContainerClassName={_cs(
headerDescriptionContainerClassName,
)}
>
{headerDescription}
</Header>
)}
{withHeaderBorder && <div className={styles.border} />}
<div className={childrenContainerClassName}>
{children}
</div>
</div>
);
}

export default Container;
4 changes: 4 additions & 0 deletions src/components/Container/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.container {
display: flex;
flex-direction: column;
}
123 changes: 123 additions & 0 deletions src/components/Header/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import { useMemo } from 'react';
import {
_cs,
isNotDefined,
} from '@togglecorp/fujs';

import Heading, { Props as HeadingProps } from '#components/Heading';
import useBasicLayout from '#hooks/useBasicLayout';

import styles from './styles.module.css';

interface Props {
className?: string;
elementRef?: React.Ref<HTMLDivElement>;

children?: React.ReactNode;
childrenContainerClassName?: string;

actions?: React.ReactNode;
actionsContainerClassName?: string;

icons?: React.ReactNode;
iconsContainerClassName?: string;

heading: React.ReactNode;
headingLevel?: HeadingProps['level'];
headingSectionClassName?: string;
headingContainerClassName?: string;
headingClassName?: string;
headingDescription?: React.ReactNode;
headingDescriptionContainerClassName?: string;
}

function Header(props: Props) {
const {
className,
elementRef,
actions,
actionsContainerClassName,
children,
childrenContainerClassName,
headingLevel,
heading,
headingClassName,
headingSectionClassName,
headingContainerClassName,
headingDescription,
headingDescriptionContainerClassName,
icons,
iconsContainerClassName,
} = props;

const headingChildren = useMemo(
() => {
if (isNotDefined(heading) && isNotDefined(headingDescription)) {
return null;
}

return (
<>
<Heading
level={headingLevel}
className={headingClassName}
>
{heading}
</Heading>
{headingDescription && (
<div className={headingDescriptionContainerClassName}>
{headingDescription}
</div>
)}
</>
);
},
[
heading,
headingDescription,
headingClassName,
headingDescriptionContainerClassName,
headingLevel,
],
);

const {
content,
containerClassName,
} = useBasicLayout({
actions,
actionsContainerClassName,
children: headingChildren,
childrenContainerClassName: headingContainerClassName,
className: headingSectionClassName,
icons,
iconsContainerClassName,
});

if (!content && !children) {
return null;
}

return (
<div
className={_cs(
styles.header,
className,
)}
ref={elementRef}
>
{content && (
<div className={containerClassName}>
{content}
</div>
)}
{children && (
<div className={childrenContainerClassName}>
{children}
</div>
)}
</div>
);
}

export default Header;
4 changes: 4 additions & 0 deletions src/components/Header/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.header {
display: flex;
flex-direction: column;
}
55 changes: 55 additions & 0 deletions src/components/Heading/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {
ElementType,
ReactNode,
useRef,
} from 'react';
import { _cs } from '@togglecorp/fujs';

import styles from './styles.module.css';

export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;

const levelToClassName: Record<HeadingLevel, string> = {
1: styles.levelOne,
2: styles.levelTwo,
3: styles.levelThree,
4: styles.levelFour,
5: styles.levelFive,
6: styles.levelSix,
};

export interface Props {
className?: string;
level?: HeadingLevel;
children: ReactNode;
}

function Heading(props: Props) {
const {
className,
level = 3,
children,
} = props;

const HeadingTag = `h${level}` as ElementType;
const headingElementRef = useRef<HTMLHeadingElement>(null);

if (!children) {
return null;
}

return (
<HeadingTag
className={_cs(
styles.heading,
levelToClassName[level],
className,
)}
ref={headingElementRef}
>
{children}
</HeadingTag>
);
}

export default Heading;
31 changes: 31 additions & 0 deletions src/components/Heading/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.heading {
--font-size: var(--cms-ui-font-size-3xl);
--line-height: var(--cms-ui-line-height-sm);
margin: 0;
line-height: var(--line-height);
font-size: var(--font-size);

&.level-one {
--font-size: var(--cms-ui-font-size-5xl);
}

&.level-two {
--font-size: var(--cms-ui-font-size-4xl);
}

&.level-three {
--font-size: var(--cms-ui-font-size-3xl);
}

&.level-four {
--font-size: var(--cms-ui-font-size-2xl);
}

&.level-five {
--font-size: var(--cms-ui-font-size-xl);
}

&.level-six {
--font-size: var(--cms-ui-font-size-lg);
}
}
46 changes: 25 additions & 21 deletions src/components/Navbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@ import {
gql,
useMutation,
} from '@apollo/client';
import { _cs, isDefined, isNotDefined } from '@togglecorp/fujs';
import {
_cs,
isDefined,
isNotDefined,
} from '@togglecorp/fujs';
import { Button } from '@togglecorp/toggle-ui';

import Heading from '#components/Heading';
import UserContext from '#contexts/user';
import {
LogoutMutation,
Expand All @@ -35,8 +40,9 @@ const LOGOUT_MUTATION = gql`

function Navbar(props: Props) {
const { className } = props;

const { userAuth, removeUserAuth } = useContext(UserContext);
console.log('user', userAuth);

const [
logout,
{ loading },
Expand All @@ -60,36 +66,34 @@ function Navbar(props: Props) {
},
},
);

const handleLogoutClick = useCallback(() => {
logout();
}, [logout]);

return (
<nav className={_cs(styles.navbar, className)}>
<Heading level={5}>
ToggTalkie
</Heading>
<div>
<Link
to="/"
>
CMS
</Link>
</div>
{isNotDefined(userAuth) && (
<div>
{isNotDefined(userAuth) && (
<Link
to="login"
>
Login
</Link>
</div>
)}
{isDefined(userAuth) && (
<Button
name="logout"
onClick={handleLogoutClick}
disabled={loading}
>
Logout
</Button>
)}
)}
{isDefined(userAuth) && (
<Button
name="logout"
onClick={handleLogoutClick}
disabled={loading}
>
Logout
</Button>
)}
</div>
</nav>
);
}
Expand Down
Loading

0 comments on commit 361029c

Please sign in to comment.