🚚(app-desk) create route teams/create
- Create the routes teams/create. - Add link to the buttons routing to this page - Adapt design
This commit is contained in:
@@ -1,13 +1,12 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Button, Field, Input } from '@openfun/cunningham-react';
|
import { Button } from '@openfun/cunningham-react';
|
||||||
import { useState } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
import { Box } from '@/components';
|
import { Box, StyledLink } from '@/components';
|
||||||
import { useCunninghamTheme } from '@/cunningham';
|
import { useCunninghamTheme } from '@/cunningham';
|
||||||
import { Panel, useCreateTeam } from '@/features';
|
import { Panel } from '@/features';
|
||||||
|
|
||||||
const StyledButton = styled(Button)`
|
const StyledButton = styled(Button)`
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
@@ -15,8 +14,6 @@ const StyledButton = styled(Button)`
|
|||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { mutate: createTeam } = useCreateTeam();
|
|
||||||
const [teamName, setTeamName] = useState('');
|
|
||||||
const { colorsTokens } = useCunninghamTheme();
|
const { colorsTokens } = useCunninghamTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -29,21 +26,9 @@ export default function Home() {
|
|||||||
$width="100%"
|
$width="100%"
|
||||||
$gap="5rem"
|
$gap="5rem"
|
||||||
>
|
>
|
||||||
<StyledButton>{t('Create a new team')}</StyledButton>
|
<StyledLink href="/teams/create">
|
||||||
<Field>
|
<StyledButton>{t('Create a new team')}</StyledButton>
|
||||||
<Input
|
</StyledLink>
|
||||||
type="text"
|
|
||||||
label={t('Team name')}
|
|
||||||
onChange={(e) => setTeamName(e.target.value)}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
fullWidth
|
|
||||||
onClick={() => createTeam(teamName)}
|
|
||||||
className="mt-s"
|
|
||||||
>
|
|
||||||
{t('Create a team')}
|
|
||||||
</Button>
|
|
||||||
</Field>
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
26
src/frontend/apps/desk/src/app/teams/create/page.tsx
Normal file
26
src/frontend/apps/desk/src/app/teams/create/page.tsx
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { Button, Field, Input } from '@openfun/cunningham-react';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
import { useCreateTeam } from '@/features';
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { mutate: createTeam } = useCreateTeam();
|
||||||
|
const [teamName, setTeamName] = useState('');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Field>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
label={t('Team name')}
|
||||||
|
onChange={(e) => setTeamName(e.target.value)}
|
||||||
|
/>
|
||||||
|
<Button fullWidth onClick={() => createTeam(teamName)} className="mt-s">
|
||||||
|
{t('Create a team')}
|
||||||
|
</Button>
|
||||||
|
</Field>
|
||||||
|
);
|
||||||
|
}
|
||||||
27
src/frontend/apps/desk/src/app/teams/layout.tsx
Normal file
27
src/frontend/apps/desk/src/app/teams/layout.tsx
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { PropsWithChildren } from 'react';
|
||||||
|
|
||||||
|
import { Box } from '@/components';
|
||||||
|
import { useCunninghamTheme } from '@/cunningham';
|
||||||
|
import { Panel } from '@/features';
|
||||||
|
|
||||||
|
export default function Layout({ children }: PropsWithChildren) {
|
||||||
|
const { colorsTokens } = useCunninghamTheme();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box $height="inherit" $direction="row">
|
||||||
|
<Panel />
|
||||||
|
<Box
|
||||||
|
$background={colorsTokens()['primary-bg']}
|
||||||
|
$justify="center"
|
||||||
|
$align="center"
|
||||||
|
$width="100%"
|
||||||
|
$gap="5rem"
|
||||||
|
$css="overflow:auto;"
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
11
src/frontend/apps/desk/src/components/Link.tsx
Normal file
11
src/frontend/apps/desk/src/components/Link.tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import Link from 'next/link';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
export const StyledLink = styled(Link)`
|
||||||
|
text-decoration: none;
|
||||||
|
color: #ffffff33;
|
||||||
|
&[aria-current='page'] {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
display: flex;
|
||||||
|
`;
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
export * from './Box';
|
export * from './Box';
|
||||||
export * from './Text';
|
export * from './Text';
|
||||||
|
export * from './Link';
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ export const Menu = () => {
|
|||||||
className="m-0 p-0"
|
className="m-0 p-0"
|
||||||
$background={colorsTokens()['primary-800']}
|
$background={colorsTokens()['primary-800']}
|
||||||
$height="100%"
|
$height="100%"
|
||||||
$width="3.75rem"
|
|
||||||
$justify="space-between"
|
$justify="space-between"
|
||||||
>
|
>
|
||||||
<Box className="pt-b" $direction="column" $gap="0.8rem">
|
<Box className="pt-b" $direction="column" $gap="0.8rem">
|
||||||
|
|||||||
@@ -1,24 +1,14 @@
|
|||||||
import { Button } from '@openfun/cunningham-react';
|
import { Button } from '@openfun/cunningham-react';
|
||||||
import Link from 'next/link';
|
|
||||||
import { usePathname } from 'next/navigation';
|
import { usePathname } from 'next/navigation';
|
||||||
import React, { useRef, useState } from 'react';
|
import React, { useRef, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import styled from 'styled-components';
|
|
||||||
|
|
||||||
import { Box } from '@/components/';
|
import { Box, StyledLink } from '@/components';
|
||||||
import { useCunninghamTheme } from '@/cunningham';
|
import { useCunninghamTheme } from '@/cunningham';
|
||||||
import { SVGComponent } from '@/types/components';
|
import { SVGComponent } from '@/types/components';
|
||||||
|
|
||||||
import { Tooltip } from './Tooltip';
|
import { Tooltip } from './Tooltip';
|
||||||
|
|
||||||
const StyledLink = styled(Link)`
|
|
||||||
text-decoration: none;
|
|
||||||
color: #ffffff33;
|
|
||||||
&[aria-current='page'] {
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
interface MenuItemProps {
|
interface MenuItemProps {
|
||||||
Icon: SVGComponent;
|
Icon: SVGComponent;
|
||||||
label: string;
|
label: string;
|
||||||
@@ -29,7 +19,7 @@ const MenuItem = ({ Icon, label, href }: MenuItemProps) => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const { colorsTokens } = useCunninghamTheme();
|
const { colorsTokens } = useCunninghamTheme();
|
||||||
const buttonRef = useRef(null);
|
const parentRef = useRef(null);
|
||||||
const [isTooltipOpen, setIsTooltipOpen] = useState(false);
|
const [isTooltipOpen, setIsTooltipOpen] = useState(false);
|
||||||
|
|
||||||
const isActive = pathname === href;
|
const isActive = pathname === href;
|
||||||
@@ -51,9 +41,10 @@ const MenuItem = ({ Icon, label, href }: MenuItemProps) => {
|
|||||||
<StyledLink
|
<StyledLink
|
||||||
href={href}
|
href={href}
|
||||||
aria-current={isActive && 'page'}
|
aria-current={isActive && 'page'}
|
||||||
ref={buttonRef}
|
ref={parentRef}
|
||||||
onMouseOver={() => setIsTooltipOpen(true)}
|
onMouseOver={() => setIsTooltipOpen(true)}
|
||||||
onMouseOut={() => setIsTooltipOpen(false)}
|
onMouseOut={() => setIsTooltipOpen(false)}
|
||||||
|
style={{ display: 'block' }}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
className="m-st p-t"
|
className="m-st p-t"
|
||||||
@@ -86,7 +77,7 @@ const MenuItem = ({ Icon, label, href }: MenuItemProps) => {
|
|||||||
</Box>
|
</Box>
|
||||||
{isTooltipOpen && (
|
{isTooltipOpen && (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
buttonRef={buttonRef}
|
parentRef={parentRef}
|
||||||
label={label}
|
label={label}
|
||||||
backgroundColor={backgroundTooltip}
|
backgroundColor={backgroundTooltip}
|
||||||
textColor={colorTooltip}
|
textColor={colorTooltip}
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ import React, { CSSProperties, useEffect, useState } from 'react';
|
|||||||
import { Box, Text } from '@/components/';
|
import { Box, Text } from '@/components/';
|
||||||
|
|
||||||
interface TooltipProps {
|
interface TooltipProps {
|
||||||
buttonRef: React.MutableRefObject<null>;
|
parentRef: React.MutableRefObject<null>;
|
||||||
textColor: CSSProperties['color'];
|
textColor: CSSProperties['color'];
|
||||||
backgroundColor: CSSProperties['color'];
|
backgroundColor: CSSProperties['color'];
|
||||||
label: string;
|
label: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Tooltip = ({
|
export const Tooltip = ({
|
||||||
buttonRef,
|
parentRef,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
textColor,
|
textColor,
|
||||||
label,
|
label,
|
||||||
@@ -23,7 +23,7 @@ export const Tooltip = ({
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover parentRef={buttonRef} onClickOutside={() => ''} borderless>
|
<Popover parentRef={parentRef} onClickOutside={() => ''} borderless>
|
||||||
<Box
|
<Box
|
||||||
aria-label="tooltip"
|
aria-label="tooltip"
|
||||||
className="ml-t p-t"
|
className="ml-t p-t"
|
||||||
|
|||||||
@@ -1,14 +1,8 @@
|
|||||||
<svg
|
<svg viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
width="30"
|
|
||||||
height="30"
|
|
||||||
viewBox="0 0 30 30"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<g clip-path="url(#clip0_178_17838)">
|
<g clip-path="url(#clip0_178_17838)">
|
||||||
<path
|
<path
|
||||||
d="M16.25 8.75H13.75V13.75H8.75V16.25H13.75V21.25H16.25V16.25H21.25V13.75H16.25V8.75ZM15 2.5C8.1 2.5 2.5 8.1 2.5 15C2.5 21.9 8.1 27.5 15 27.5C21.9 27.5 27.5 21.9 27.5 15C27.5 8.1 21.9 2.5 15 2.5ZM15 25C9.4875 25 5 20.5125 5 15C5 9.4875 9.4875 5 15 5C20.5125 5 25 9.4875 25 15C25 20.5125 20.5125 25 15 25Z"
|
d="M16.25 8.75H13.75V13.75H8.75V16.25H13.75V21.25H16.25V16.25H21.25V13.75H16.25V8.75ZM15 2.5C8.1 2.5 2.5 8.1 2.5 15C2.5 21.9 8.1 27.5 15 27.5C21.9 27.5 27.5 21.9 27.5 15C27.5 8.1 21.9 2.5 15 2.5ZM15 25C9.4875 25 5 20.5125 5 15C5 9.4875 9.4875 5 15 5C20.5125 5 25 9.4875 25 15C25 20.5125 20.5125 25 15 25Z"
|
||||||
fill="#000091"
|
fill="currentColor"
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
<defs>
|
<defs>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 633 B After Width: | Height: | Size: 604 B |
@@ -1,14 +1,8 @@
|
|||||||
<svg
|
<svg viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
width="30"
|
|
||||||
height="30"
|
|
||||||
viewBox="0 0 30 30"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<g clip-path="url(#clip0_178_17837)">
|
<g clip-path="url(#clip0_178_17837)">
|
||||||
<path
|
<path
|
||||||
d="M11.25 3.75L6.25 8.7375H10V17.5H12.5V8.7375H16.25L11.25 3.75ZM20 21.2625V12.5H17.5V21.2625H13.75L18.75 26.25L23.75 21.2625H20Z"
|
d="M11.25 3.75L6.25 8.7375H10V17.5H12.5V8.7375H16.25L11.25 3.75ZM20 21.2625V12.5H17.5V21.2625H13.75L18.75 26.25L23.75 21.2625H20Z"
|
||||||
fill="#000091"
|
fill="currentColor"
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
<defs>
|
<defs>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 458 B After Width: | Height: | Size: 429 B |
@@ -1,41 +1,75 @@
|
|||||||
import { Button } from '@openfun/cunningham-react';
|
import { Button } from '@openfun/cunningham-react';
|
||||||
import Image from 'next/image';
|
import React, { CSSProperties } from 'react';
|
||||||
import React from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
import { Box } from '@/components';
|
import { Box, StyledLink } from '@/components';
|
||||||
|
import { useCunninghamTheme } from '@/cunningham';
|
||||||
|
|
||||||
import { default as IconAdd } from '../assets/icon-add.svg?url';
|
import { TeamsOrdering } from '../api/useTeams';
|
||||||
import { default as IconSort } from '../assets/icon-sort.svg?url';
|
import IconAdd from '../assets/icon-add.svg';
|
||||||
|
import IconSort from '../assets/icon-sort.svg';
|
||||||
import { useTeamStore } from '../store/useTeamsStore';
|
import { useTeamStore } from '../store/useTeamsStore';
|
||||||
|
|
||||||
|
const ButtonSort = styled(Button)<{
|
||||||
|
$background: CSSProperties['background'];
|
||||||
|
$color: CSSProperties['color'];
|
||||||
|
}>`
|
||||||
|
&.c__button {
|
||||||
|
svg {
|
||||||
|
background-color: transparent;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.c__button--active svg {
|
||||||
|
background-color: ${({ $background }) => $background};
|
||||||
|
border-radius: 10rem;
|
||||||
|
color: ${({ $color }) => $color};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export const PanelActions = () => {
|
export const PanelActions = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const changeOrdering = useTeamStore((state) => state.changeOrdering);
|
const { changeOrdering, ordering } = useTeamStore();
|
||||||
|
const { colorsTokens } = useCunninghamTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
$direction="row"
|
$direction="row"
|
||||||
$gap="1rem"
|
$gap="1rem"
|
||||||
$css={`
|
$css={`
|
||||||
& > button {
|
& button {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
padding: 0.1rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
<Button
|
<ButtonSort
|
||||||
aria-label={t('Sort the teams')}
|
aria-label={t('Sort the teams')}
|
||||||
icon={<Image priority src={IconSort} alt={t('Sort teams icon')} />}
|
icon={
|
||||||
|
<IconSort width={30} height={30} aria-label={t('Sort teams icon')} />
|
||||||
|
}
|
||||||
color="tertiary"
|
color="tertiary"
|
||||||
className="c__button-no-bg p-0 m-0"
|
className="c__button-no-bg p-0 m-0"
|
||||||
onClick={changeOrdering}
|
onClick={changeOrdering}
|
||||||
|
active={ordering === TeamsOrdering.BY_CREATED_ON}
|
||||||
|
$background={colorsTokens()['primary-200']}
|
||||||
|
$color={colorsTokens()['primary-600']}
|
||||||
/>
|
/>
|
||||||
<Button
|
<StyledLink href="/teams/create">
|
||||||
aria-label={t('Add a team')}
|
<Button
|
||||||
icon={<Image priority src={IconAdd} alt={t('Add team icon')} />}
|
aria-label={t('Add a team')}
|
||||||
color="tertiary"
|
icon={
|
||||||
className="c__button-no-bg p-0 m-0"
|
<IconAdd width={30} height={30} aria-label={t('Add team icon')} />
|
||||||
/>
|
}
|
||||||
|
color="tertiary"
|
||||||
|
className="c__button-no-bg p-0 m-0"
|
||||||
|
/>
|
||||||
|
</StyledLink>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user