(app-desk) add interaction to sort button

In the team panel, we have the possibility to sort the teams.
This commit adds the interaction to the button.
This commit is contained in:
Anthony LC
2024-02-01 15:33:53 +01:00
committed by Anthony LC
parent 36e2dc2378
commit fafffd2391
10 changed files with 125 additions and 22 deletions

View File

@@ -4,3 +4,22 @@ body {
margin: 0;
padding: 0;
}
::-webkit-scrollbar {
width: 20px;
}
::-webkit-scrollbar-track {
background-color: transparent;
}
::-webkit-scrollbar-thumb {
background-color: #d6dee1;
border-radius: 20px;
border: 6px solid transparent;
background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover {
background-color: #a8bbbf;
}

View File

@@ -1,12 +1,13 @@
'use client';
import { Button } from '@openfun/cunningham-react';
import { Button, Field, Input } from '@openfun/cunningham-react';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';
import { Box } from '@/components';
import { useCunninghamTheme } from '@/cunningham';
import { Panel } from '@/features';
import { Panel, useCreateTeam } from '@/features';
const StyledButton = styled(Button)`
width: fit-content;
@@ -14,6 +15,8 @@ const StyledButton = styled(Button)`
export default function Home() {
const { t } = useTranslation();
const { mutate: createTeam } = useCreateTeam();
const [teamName, setTeamName] = useState('');
const { colorsTokens } = useCunninghamTheme();
return (
@@ -24,8 +27,23 @@ export default function Home() {
$justify="center"
$align="center"
$width="100%"
$gap="5rem"
>
<StyledButton>{t('Create a new group')}</StyledButton>
<StyledButton>{t('Create a new team')}</StyledButton>
<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>
</Box>
</Box>
);

View File

@@ -0,0 +1 @@
export * from './useCreateTeam';

View File

@@ -34,7 +34,6 @@ export function useCreateTeam() {
onSuccess: () => {
void queryClient.invalidateQueries({
queryKey: [KEY_LIST_TEAM],
exact: true,
});
},
});

View File

@@ -20,13 +20,24 @@ interface TeamResponse {
accesses: Access[];
}
export enum TeamsOrdering {
BY_CREATED_ON = 'created_at',
BY_CREATED_ON_DESC = '-created_at',
}
export type TeamsParams = {
ordering?: TeamsOrdering;
};
type TeamsResponse = APIList<TeamResponse>;
export interface TeamsResponseError {
detail: string;
}
export const getTeams = async () => {
const response = await fetchAPI(`teams/`);
export const getTeams = async (props?: TeamsParams) => {
const response = await fetchAPI(
`teams/${props?.ordering ? `?ordering=${props.ordering}` : ''}`,
);
if (!response.ok) {
throw new Error(`Couldn't fetch teams: ${response.statusText}`);
@@ -37,6 +48,7 @@ export const getTeams = async () => {
export const KEY_LIST_TEAM = 'teams';
export function useTeams(
param?: TeamsParams,
queryConfig?: UseQueryOptions<
TeamsResponse,
TeamsResponseError,
@@ -44,8 +56,8 @@ export function useTeams(
>,
) {
return useQuery<TeamsResponse, TeamsResponseError, TeamsResponse>({
queryKey: [KEY_LIST_TEAM],
queryFn: getTeams,
queryKey: [KEY_LIST_TEAM, param],
queryFn: () => getTeams(param),
...queryConfig,
});
}

View File

@@ -7,9 +7,11 @@ import { Box } from '@/components';
import { default as IconAdd } from '../assets/icon-add.svg?url';
import { default as IconSort } from '../assets/icon-sort.svg?url';
import { useTeamStore } from '../store/useTeamsStore';
export const PanelActions = () => {
const { t } = useTranslation();
const changeOrdering = useTeamStore((state) => state.changeOrdering);
return (
<Box
@@ -26,6 +28,7 @@ export const PanelActions = () => {
icon={<Image priority src={IconSort} alt={t('Sort teams icon')} />}
color="tertiary"
className="c__button-no-bg p-0 m-0"
onClick={changeOrdering}
/>
<Button
aria-label={t('Add a team')}

View File

@@ -8,9 +8,13 @@ import { useCunninghamTheme } from '@/cunningham';
import { useTeams } from '../api/useTeams';
import IconNone from '../assets/icon-none.svg';
import { useTeamStore } from '../store/useTeamsStore';
export const PanelTeams = () => {
const { data, isPending, isError } = useTeams();
const ordering = useTeamStore((state) => state.ordering);
const { data, isPending, isError } = useTeams({
ordering,
});
const { t } = useTranslation();
const { colorsTokens } = useCunninghamTheme();
@@ -48,7 +52,7 @@ export const PanelTeams = () => {
}
return (
<Box as="ul" $gap="1rem" className="p-s mt-t">
<Box as="ul" $gap="1rem" className="p-s mt-t" $css="overflow:auto;">
{data?.results.map((team) => (
<Box
as="li"

View File

@@ -1 +1,2 @@
export * from './components/Panel';
export * from './components';
export * from './api';

View File

@@ -0,0 +1,19 @@
import { create } from 'zustand';
import { TeamsOrdering } from '../api/useTeams';
interface TeamsStore {
ordering: TeamsOrdering;
changeOrdering: () => void;
}
export const useTeamStore = create<TeamsStore>((set) => ({
ordering: TeamsOrdering.BY_CREATED_ON_DESC,
changeOrdering: () =>
set(({ ordering }) => ({
ordering:
ordering === TeamsOrdering.BY_CREATED_ON
? TeamsOrdering.BY_CREATED_ON_DESC
: TeamsOrdering.BY_CREATED_ON,
})),
}));