diff --git a/web/usuaris/CHANGELOG.md b/web/usuaris/CHANGELOG.md index b3b29cec0..2d1e50736 100644 --- a/web/usuaris/CHANGELOG.md +++ b/web/usuaris/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. +## [0.22.0] - 2024-06-04 + +### Added + +- Added Mentors page +- Added Dashboard component + ## [0.21.1] - 2024-05-22 ### Changed diff --git a/web/usuaris/package-lock.json b/web/usuaris/package-lock.json index ee81bd976..b83573617 100644 --- a/web/usuaris/package-lock.json +++ b/web/usuaris/package-lock.json @@ -1,12 +1,12 @@ { "name": "web_usuaris", - "version": "0.20.0", + "version": "0.22.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "web_usuaris", - "version": "0.20.0", + "version": "0.22.0", "dependencies": { "@hookform/resolvers": "^3.0.0", "@itacademy/schemas": "^0.3.0", @@ -31,6 +31,7 @@ "@tanstack/eslint-plugin-query": "4.29.4", "@testing-library/jest-dom": "6.2.1", "@testing-library/react": "14.1.2", + "@testing-library/user-event": "^14.5.2", "@types/jsdom": "21.1.1", "@types/qs": "6.9.7", "@types/react": "^18.2.43", @@ -1995,6 +1996,19 @@ "react-dom": "^18.0.0" } }, + "node_modules/@testing-library/user-event": { + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", + "dev": true, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -8419,4 +8433,4 @@ } } } -} \ No newline at end of file +} diff --git a/web/usuaris/package.json b/web/usuaris/package.json index fc02af7a6..99bbf0d08 100644 --- a/web/usuaris/package.json +++ b/web/usuaris/package.json @@ -1,7 +1,7 @@ { "name": "web_usuaris", "private": true, - "version": "0.21.1", + "version": "0.22.0", "type": "module", "scripts": { "dev": "vite", @@ -35,6 +35,7 @@ "@tanstack/eslint-plugin-query": "4.29.4", "@testing-library/jest-dom": "6.2.1", "@testing-library/react": "14.1.2", + "@testing-library/user-event": "^14.5.2", "@types/jsdom": "21.1.1", "@types/qs": "6.9.7", "@types/react": "^18.2.43", diff --git a/web/usuaris/src/__mocks__/handlers.ts b/web/usuaris/src/__mocks__/handlers.ts index a52983971..d2233ef0f 100644 --- a/web/usuaris/src/__mocks__/handlers.ts +++ b/web/usuaris/src/__mocks__/handlers.ts @@ -1,7 +1,6 @@ import { HttpResponse, http } from 'msw' import { urls } from '../constants' -import { UserStatus } from '../types' -import { UserRole } from '../types/types' +import { UserRole, UserStatus } from '../types' export const handlers = [ http.get(urls.getUsers, ({ request }) => { diff --git a/web/usuaris/src/__tests__/context/AuthProvider.test.tsx b/web/usuaris/src/__tests__/context/AuthProvider.test.tsx index ae3cc78a8..5e3e860f7 100644 --- a/web/usuaris/src/__tests__/context/AuthProvider.test.tsx +++ b/web/usuaris/src/__tests__/context/AuthProvider.test.tsx @@ -2,11 +2,12 @@ import { ReactElement } from 'react' import { renderHook } from '@testing-library/react' import { act } from 'react-dom/test-utils' import { AuthProvider, useAuth, type TUser } from '../../context/AuthProvider' +import { UserRole } from '../../types' const mockUser: TUser = { dni: '12345678A', email: 'user@example.cat', - role: 'ADMIN', + role: UserRole.ADMIN, } describe('AuthProvider', () => { it('should render children', () => { diff --git a/web/usuaris/src/__tests__/hooks/useGetUsers.test.tsx b/web/usuaris/src/__tests__/hooks/useGetUsers.test.tsx index c920c5e50..6a226343f 100644 --- a/web/usuaris/src/__tests__/hooks/useGetUsers.test.tsx +++ b/web/usuaris/src/__tests__/hooks/useGetUsers.test.tsx @@ -3,8 +3,7 @@ import { useGetUsers } from '../../hooks/useGetUsers' import { renderHook, waitFor } from '../test-utils' import { queryClient } from '../setup' import { type TFilters } from '../../types' -import { UserStatus } from '../../types' -import { UserRole } from '../../types/types' +import { UserRole, UserStatus } from '../../types' describe('useGetUsers', () => { it('fetches users successfully', async () => { diff --git a/web/usuaris/src/__tests__/main.test.tsx b/web/usuaris/src/__tests__/main.test.tsx index 2e7ba2696..8234785be 100644 --- a/web/usuaris/src/__tests__/main.test.tsx +++ b/web/usuaris/src/__tests__/main.test.tsx @@ -4,9 +4,10 @@ import { createGlobalStyle } from 'styled-components' import { font } from '@itacademy/ui' import { QueryClientProvider } from '@tanstack/react-query' import { queryClient } from './setup' -import { ErrorPage, Home } from '../pages' +import { ErrorPage, Home, Mentors } from '../pages' import { Layout } from '../components/layout' import { AuthProvider } from '../context/AuthProvider' +import { paths } from '../constants' describe('main', () => { it('renders correctly', () => { @@ -18,10 +19,14 @@ describe('main', () => { const routes = [ { - path: '/', + path: paths.home, element: , errorElement: , }, + { + path: paths.mentors, + element: , + }, ] const router = createMemoryRouter(routes, { diff --git a/web/usuaris/src/__tests__/molecules/RoleFilter.test.tsx b/web/usuaris/src/__tests__/molecules/RoleFilter.test.tsx index 82067f1af..d075ef468 100644 --- a/web/usuaris/src/__tests__/molecules/RoleFilter.test.tsx +++ b/web/usuaris/src/__tests__/molecules/RoleFilter.test.tsx @@ -1,7 +1,7 @@ import { vi } from 'vitest' import { fireEvent, render, screen, waitFor } from '../test-utils' import { RoleFilter } from '../../components/molecules/RoleFilter' -import { UserRole } from '../../types/types' +import { UserRole } from '../../types' import { roles } from '../../constants' const mockHandleClick = vi.fn() diff --git a/web/usuaris/src/__tests__/organisms/Dashboard.test.tsx b/web/usuaris/src/__tests__/organisms/Dashboard.test.tsx new file mode 100644 index 000000000..93d8c2690 --- /dev/null +++ b/web/usuaris/src/__tests__/organisms/Dashboard.test.tsx @@ -0,0 +1,19 @@ +import { screen } from '@testing-library/react' +import { render } from '../test-utils' +import { Dashboard } from '../../components/organisms' + +describe('Dashboard', () => { + it('renders correctly', () => { + render() + + const mainDiv = screen.getByRole('main') + const sideMenuElement = screen.getByText(/Mentors/i) + const filtersWidgetElement = screen.getByAltText(/Calendar/i) + const actionsDropdown = screen.getByTestId('actions-dropdown') + + expect(mainDiv).toBeInTheDocument() + expect(sideMenuElement).toBeInTheDocument() + expect(filtersWidgetElement).toBeInTheDocument() + expect(actionsDropdown).toBeInTheDocument() + }) +}) diff --git a/web/usuaris/src/__tests__/organisms/SideMenu.test.tsx b/web/usuaris/src/__tests__/organisms/SideMenu.test.tsx index 82cbf1bd6..e62e0193b 100644 --- a/web/usuaris/src/__tests__/organisms/SideMenu.test.tsx +++ b/web/usuaris/src/__tests__/organisms/SideMenu.test.tsx @@ -1,48 +1,69 @@ -import { fireEvent, screen } from '@testing-library/react' +import { fireEvent, screen, waitFor } from '@testing-library/react' +import userEvent from '@testing-library/user-event' import { colors } from '@itacademy/ui' -import { describe, beforeEach, it, expect } from 'vitest' import { render } from '../test-utils' import { SideMenu } from '../../components/organisms' +import { paths } from '../../constants' describe('SideMenu', () => { beforeEach(() => { render() }) - it('renders correctly', () => { + it('renders correctly', async () => { expect(screen.getByAltText('IT Academy')).toBeInTheDocument() - expect(screen.getByText('Usuaris')).toBeInTheDocument() - expect(screen.getByText('Mentors')).toBeInTheDocument() - expect(screen.getByText('Connector')).toBeInTheDocument() - expect(screen.getByText('Configuració')).toBeInTheDocument() - }) + const usersItem = screen.getByTestId('test-title-Usuarios') + const mentorsItem = screen.getByTestId('test-title-Mentores') + const connectorItem = screen.getByTestId('test-title-Connector') + const settingsItem = screen.getByTestId('test-title-Configuración') - it('navigates to the correct page when a menu item is clicked', () => { - const firstMenuItem = screen.getByText('Usuaris') - fireEvent.click(firstMenuItem) - expect(window.location.pathname).toEqual('/') - }) + expect(usersItem).toBeInTheDocument() + expect(mentorsItem).toBeInTheDocument() + expect(connectorItem).toBeInTheDocument() + expect(settingsItem).toBeInTheDocument() - it('changes style on hover over a category', () => { - const category = screen.getByText('Usuaris') - fireEvent.mouseOver(category) - expect(category).toHaveStyle(`color: ${colors.primary}`) + expect(screen.getAllByTestId('test-icon-person').length).toBe(2) + expect(screen.getByTestId('test-icon-bolt')).toBeInTheDocument() + expect(screen.getByTestId('test-icon-settings')).toBeInTheDocument() + + waitFor(() => { + expect(usersItem).toHaveStyle(`color: ${colors.black.black3}`) + expect(mentorsItem).toHaveStyle(`color: ${colors.gray.gray3}`) + expect(connectorItem).toHaveStyle(`color: ${colors.gray.gray3}`) + expect(settingsItem).toHaveStyle(`color: ${colors.gray.gray3}`) + }) }) - it('displays the correct icons for each menu item', () => { - const personIcons = screen.getAllByTestId('person') - expect(personIcons.length).toBe(2) + it('navigates to the correct page when a menu item is clicked and changes styles', async () => { + const mentorsMenuItemLink = screen.getByTestId('test-link-Mentores') + const mentorsTitle = screen.getByTestId('test-title-Mentores') + + expect(screen.getByTestId(`test-path-${paths.home}`)).toBeInTheDocument() + waitFor(() => { + expect(mentorsTitle).toHaveStyle(`color: ${colors.gray.gray3}`) + }) - const boltIcon = screen.getByTestId('bolt') - expect(boltIcon).toBeInTheDocument() + await userEvent.click(mentorsMenuItemLink) + + expect(screen.getByTestId(`test-path-${paths.mentors}`)).toBeInTheDocument() + waitFor(() => { + expect(mentorsTitle).toHaveStyle(`color: ${colors.black.black3}`) + }) + }) + + it('changes style on hover over a category', () => { + const activeCategory = screen.getByText('Usuaris') + fireEvent.mouseOver(activeCategory) + expect(activeCategory).toHaveStyle(`color: ${colors.black.black3}`) - const settingsIcon = screen.getByTestId('settings') - expect(settingsIcon).toBeInTheDocument() + const inactiveCategory = screen.getByText('Mentors') + fireEvent.mouseOver(inactiveCategory) + expect(inactiveCategory).toHaveStyle(`color: ${colors.primary}`) }) it('ensures menu items are focusable for accessibility', () => { - const firstMenuItem = screen.getByText('Usuaris') - firstMenuItem.focus() - expect(firstMenuItem).toHaveFocus() + const usersMenuItem = screen.getByTestId('test-link-Usuarios') + usersMenuItem.focus() + expect(usersMenuItem).toHaveFocus() }) }) diff --git a/web/usuaris/src/__tests__/organisms/UsersTable.test.tsx b/web/usuaris/src/__tests__/organisms/UsersTable.test.tsx index ee57f5dd6..b414d4fe5 100644 --- a/web/usuaris/src/__tests__/organisms/UsersTable.test.tsx +++ b/web/usuaris/src/__tests__/organisms/UsersTable.test.tsx @@ -2,8 +2,7 @@ import { fireEvent, render, screen, waitFor } from '../test-utils' import { UsersTable } from '../../components/organisms' import { errorHandlers } from '../../__mocks__/handlers' import { server } from '../../__mocks__/server' -import { UserStatus } from '../../types' -import { UserRole } from '../../types/types' +import { UserRole, UserStatus } from '../../types' const defaultProps = { filtersSelected: {}, diff --git a/web/usuaris/src/__tests__/pages/Home.test.tsx b/web/usuaris/src/__tests__/pages/Home.test.tsx index d303fceca..b62c69d3e 100644 --- a/web/usuaris/src/__tests__/pages/Home.test.tsx +++ b/web/usuaris/src/__tests__/pages/Home.test.tsx @@ -2,6 +2,7 @@ import { screen } from '@testing-library/react' import { render } from '../test-utils' import { Home } from '../../pages' import { TAuthContext, useAuth } from '../../context/AuthProvider' +import { UserRole } from '../../types' describe('Home page', () => { beforeEach(() => { @@ -24,25 +25,17 @@ describe('Home page', () => { expect(screen.getByTestId('login-test')).toBeInTheDocument() }) - it('renders dashboard if user is logged in', () => { + it('renders Dashboard if user is logged in', () => { vi.mocked(useAuth).mockReturnValue({ user: { dni: '12345678A', email: 'user@example.cat', - role: 'ADMIN', + role: UserRole.ADMIN, }, } as TAuthContext) render() - const mainDiv = screen.getByRole('main') - const sideMenuElement = screen.getByText(/Mentors/i) - const filtersWidgetElement = screen.getByAltText(/Calendar/i) - const actionsDropdown = screen.getByTestId('actions-dropdown') - - expect(mainDiv).toBeInTheDocument() - expect(sideMenuElement).toBeInTheDocument() - expect(filtersWidgetElement).toBeInTheDocument() - expect(actionsDropdown).toBeInTheDocument() + expect(screen.getByTestId('dashboard-test')).toBeInTheDocument() }) }) diff --git a/web/usuaris/src/__tests__/pages/Mentors.test.tsx b/web/usuaris/src/__tests__/pages/Mentors.test.tsx new file mode 100644 index 000000000..f2f9c98cf --- /dev/null +++ b/web/usuaris/src/__tests__/pages/Mentors.test.tsx @@ -0,0 +1,32 @@ +import { screen } from '@testing-library/react' +import { render } from '../test-utils' +import { Mentors } from '../../pages' +import { TAuthContext, useAuth } from '../../context/AuthProvider' +import { UserRole } from '../../types' +import { paths } from '../../constants' + +describe('Mentors page', () => { + beforeEach(() => { + vi.mock('../../context/AuthProvider', async () => { + const actual = await vi.importActual('../../context/AuthProvider') + return { + ...actual, + useAuth: vi.fn(), + } + }) + }) + + it('renders correctly Mentors page if Admin user is logged in', () => { + vi.mocked(useAuth).mockReturnValue({ + user: { + dni: '12345678A', + email: 'user@example.cat', + role: UserRole.ADMIN, + }, + } as TAuthContext) + + render(, { initialEntries: [paths.mentors] }) + + expect(screen.getByTestId('test-mentors-page')).toBeInTheDocument() + }) +}) diff --git a/web/usuaris/src/components/molecules/RoleFilter.tsx b/web/usuaris/src/components/molecules/RoleFilter.tsx index 57771dc34..7c98a05ad 100644 --- a/web/usuaris/src/components/molecules/RoleFilter.tsx +++ b/web/usuaris/src/components/molecules/RoleFilter.tsx @@ -8,15 +8,26 @@ import { type TDropdownOption, } from '@itacademy/ui' import { useTranslation } from 'react-i18next' -import { TRole } from '../../types/types' -import { roles } from '../../constants' +import { useLocation } from 'react-router-dom' +import { TRole, UserRole } from '../../types' +import { paths, roles } from '../../constants' + +type TStyledDropdown = { + disabled?: boolean +} + +const StyledDropdown = styled(Dropdown)` + && div { + cursor: ${({ disabled }) => (disabled && 'not-allowed') || 'pointer'}; + } -const StyledDropdown = styled(Dropdown)` && button { width: 210px; padding: ${dimensions.spacing.xxs}; font-size: ${font.xs}; font-weight: 500; + opacity: ${({ disabled }) => (disabled && '0.6') || '1'}; + pointer-events: ${({ disabled }) => (disabled && 'none') || 'auto'}; &:hover { background-color: ${colors.primary}; @@ -36,6 +47,7 @@ type TRoleFilter = { export const RoleFilter: FC = ({ handleRole }) => { const { t } = useTranslation() + const { pathname } = useLocation() const handleSelectedValue = (selectedOption: TDropdownOption | undefined) => { if (selectedOption) { @@ -50,6 +62,15 @@ export const RoleFilter: FC = ({ handleRole }) => { } } + if (pathname === paths.mentors) + return ( + + ) + return roles && roles.length > 0 ? ( { + const { pathname } = useLocation() + const { changeUsersStatus, isSuccess: statusSuccess } = useUpdateUsersStatus() + + const [filters, setFilters] = useState({}) + const [selectedStatus, setSelectedStatus] = useState( + undefined + ) + const [selectedUsers, setSelectedUsers] = useState([]) + const [isActionFinished, setIsActionFinished] = useState(false) + const [isModalOpen, setIsModalOpen] = useState(false) + + useEffect(() => { + if (pathname === paths.mentors) { + setFilters({ role: UserRole.MENTOR }) + } + }, [pathname]) + + const handleSelectedUsers = (users: string[]) => { + setSelectedUsers(users) + } + + const handleAction = (action: string | undefined) => { + setIsActionFinished(false) + if (action && action !== 'DELETE') { + const updatedUsersStatus: TUpdatedUsersStatus = { + ids: selectedUsers, + status: action, + } + changeUsersStatus.mutate(updatedUsersStatus) + } else { + setIsModalOpen(!isModalOpen) + } + } + + useEffect(() => { + if (statusSuccess) { + setSelectedStatus(undefined) + setIsActionFinished(true) + } + }, [statusSuccess]) + + return ( + <> + + + + + + + + + + + + + + { + setIsModalOpen(false) + setSelectedStatus(undefined) + setIsActionFinished(true) + }} + idsToDelete={selectedUsers} + /> + + ) +} diff --git a/web/usuaris/src/components/organisms/SideMenu.tsx b/web/usuaris/src/components/organisms/SideMenu.tsx index c094cb896..7c984d6d3 100644 --- a/web/usuaris/src/components/organisms/SideMenu.tsx +++ b/web/usuaris/src/components/organisms/SideMenu.tsx @@ -1,87 +1,55 @@ import { FC } from 'react' import { FlexBox, Icon, colors, dimensions, font } from '@itacademy/ui' import styled from 'styled-components' -import { Link } from 'react-router-dom' +import { Link, useLocation } from 'react-router-dom' import { useTranslation } from 'react-i18next' import { icons } from '../../assets/icons' - -const LinkCategory = styled(Link)` - color: ${colors.gray.gray3}; - font-size: ${font.xs}; - font-weight: 600; - font-family: ${font.fontFamily}; - cursor: pointer; - text-decoration: none; - - &:hover { - color: ${colors.primary}; - } -` - -const Grid = styled.div` - display: grid; - grid-template-columns: auto 1fr; - gap: ${dimensions.spacing.xxxs}; - align-items: center; -` +import { paths, sections } from '../../constants' const SideMenuStyled = styled(FlexBox)` height: 100%; min-width: 12rem; - margin-top: ${dimensions.spacing.lg}; - - ul { - list-style: none; - padding: ${dimensions.spacing.xxxs}; - } - - li { - font-size: ${font.xs}; - font-weight: ${font.medium}; - margin-bottom: ${dimensions.spacing.xxl}; + margin-top: ${dimensions.spacing.xxs}; +` - &::before { - font-size: larger; - color: ${colors.primary}; - margin-right: 0.3rem; - } - } +const LinkSection = styled(Link)` + text-decoration: none; + margin: ${dimensions.spacing.none}; + padding: ${dimensions.spacing.xxxs}; ` -const CategoryStyled = styled.span` - color: ${colors.gray.gray3}; +type TSectionStyled = { + active?: boolean +} + +const SectionStyled = styled.span` + color: ${({ active }) => (active ? colors.black.black3 : colors.gray.gray3)}; font-size: ${font.xs}; - font-weight: 600; + font-weight: ${font.medium}; font-family: ${font.fontFamily}; cursor: pointer; transition: transform 0.3s ease; outline: none; - display: inline-block; - border: 0px solid black; - tabindex: 0; &:hover { - color: ${colors.primary}; + color: ${({ active }) => (active ? colors.black.black3 : colors.primary)}; transform: scale(1.05); } - &:focus { - color: ${colors.black.black1}; - } - - &:focus::before { - content: '●'; + &::before { + content: '${({ active }) => (active ? '●' : '')}'; font-size: larger; color: ${colors.primary}; - margin-right: 0.3rem; + margin-right: ${dimensions.spacing.xxxs}; } ` const ImgStyled = styled(Icon)` - height: 30px; - margin-right: ${dimensions.spacing.xxxs}; - &[data-testid] + height: ${dimensions.spacing.lg}; + + &[data-testid] { content: attr(data-testid); + } ` const LogoImage = styled.img` @@ -89,55 +57,43 @@ const LogoImage = styled.img` height: auto; ` -const menu = [ - { - id: 1, - title: 'Usuarios', - icon: 'person', - link: '/#', - }, - { - id: 2, - title: 'Mentores', - icon: 'person', - link: '/#', - }, - { - id: 3, - title: 'Connector', - icon: 'bolt', - link: '/#', - }, - { - id: 4, - title: 'Configuración', - icon: 'settings', - link: '/#', - }, -] - export const SideMenu: FC = () => { const { t } = useTranslation() + const { pathname } = useLocation() return ( - - -
    - {menu.map((item) => ( -
  • - + + + + + + {sections.map((item) => ( + + - - {t(item.title)} - - -
  • + + {t(item.title)} + + + ))} -
+
) diff --git a/web/usuaris/src/components/organisms/UsersTable/UsersTable.tsx b/web/usuaris/src/components/organisms/UsersTable/index.tsx similarity index 98% rename from web/usuaris/src/components/organisms/UsersTable/UsersTable.tsx rename to web/usuaris/src/components/organisms/UsersTable/index.tsx index ef6e1ba86..5633813d9 100644 --- a/web/usuaris/src/components/organisms/UsersTable/UsersTable.tsx +++ b/web/usuaris/src/components/organisms/UsersTable/index.tsx @@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next' import { ColumnDef, createColumnHelper } from '@tanstack/react-table' import { Checkbox, Spinner, dimensions } from '@itacademy/ui' import { DeleteConfirmationModal, Table } from '../../molecules' -import { TFilters, TUserData, UserStatus } from '../../../types' +import { TFilters, TUserData, UserRole, UserStatus } from '../../../types' import { icons } from '../../../assets/icons' import { useGetUsers, useUpdateUser } from '../../../hooks' import { @@ -17,7 +17,6 @@ import { StatusStyled, TableContainer, } from './UsersTable.styles' -import { UserRole } from '../../../types/types' type TUsersTable = { filtersSelected: TFilters | Record diff --git a/web/usuaris/src/components/organisms/index.ts b/web/usuaris/src/components/organisms/index.ts index e3ab6c551..bcd712756 100644 --- a/web/usuaris/src/components/organisms/index.ts +++ b/web/usuaris/src/components/organisms/index.ts @@ -1,5 +1,6 @@ +export { Dashboard } from './Dashboard' export { FiltersWidget } from './FiltersWidget' export { Login } from './Login' export { Navbar } from './Navbar' export { SideMenu } from './SideMenu' -export { UsersTable } from './UsersTable/UsersTable' +export { UsersTable } from './UsersTable' diff --git a/web/usuaris/src/constants/index.ts b/web/usuaris/src/constants/index.ts index 77ac9281f..b27ad7ce3 100644 --- a/web/usuaris/src/constants/index.ts +++ b/web/usuaris/src/constants/index.ts @@ -1,4 +1,5 @@ -export { urls } from './urls' +export { languages, type Language } from './languages' export { paths } from './paths' export { roles } from './roles' -export { languages, type Language } from './languages' +export { sections } from './sections' +export { urls } from './urls' diff --git a/web/usuaris/src/constants/paths.ts b/web/usuaris/src/constants/paths.ts index 9fd9a32a9..9eb0364ad 100644 --- a/web/usuaris/src/constants/paths.ts +++ b/web/usuaris/src/constants/paths.ts @@ -1,3 +1,4 @@ export const paths = { home: '/', + mentors: '/mentors', } diff --git a/web/usuaris/src/constants/roles.ts b/web/usuaris/src/constants/roles.ts index 4366a761a..944e5e9eb 100644 --- a/web/usuaris/src/constants/roles.ts +++ b/web/usuaris/src/constants/roles.ts @@ -1,5 +1,5 @@ import i18n from '../i18n' -import { TRole, UserRole } from '../types/types' +import { TRole, UserRole } from '../types' type TRoleKey = keyof typeof UserRole diff --git a/web/usuaris/src/constants/sections.ts b/web/usuaris/src/constants/sections.ts new file mode 100644 index 000000000..3575ab741 --- /dev/null +++ b/web/usuaris/src/constants/sections.ts @@ -0,0 +1,35 @@ +import { paths } from './paths' + +type TSection = { + id: number + title: string + icon: string + path: string +} + +export const sections: TSection[] = [ + { + id: 1, + title: 'Usuarios', + icon: 'person', + path: paths.home, + }, + { + id: 2, + title: 'Mentores', + icon: 'person', + path: paths.mentors, + }, + { + id: 3, + title: 'Connector', + icon: 'bolt', + path: '/#', + }, + { + id: 4, + title: 'Configuración', + icon: 'settings', + path: '/#', + }, +] diff --git a/web/usuaris/src/context/AuthProvider.tsx b/web/usuaris/src/context/AuthProvider.tsx index 3db50218b..72dde2a65 100644 --- a/web/usuaris/src/context/AuthProvider.tsx +++ b/web/usuaris/src/context/AuthProvider.tsx @@ -6,11 +6,12 @@ import React, { useState, } from 'react' import { urls } from '../constants' +import { UserRole } from '../types' export type TUser = { dni: string email: string - role: 'ADMIN' + role: UserRole } | null export type TAuthContext = { diff --git a/web/usuaris/src/main.tsx b/web/usuaris/src/main.tsx index 27b7db249..a71a98384 100644 --- a/web/usuaris/src/main.tsx +++ b/web/usuaris/src/main.tsx @@ -6,7 +6,7 @@ import { RouterProvider, createBrowserRouter } from 'react-router-dom' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { font } from '@itacademy/ui' import { paths } from './constants/paths' -import { ErrorPage, Home } from './pages' +import { ErrorPage, Home, Mentors } from './pages' import { Layout } from './components/layout' import './i18n' import { AuthProvider } from './context/AuthProvider' @@ -22,6 +22,10 @@ const router = createBrowserRouter([ element: , errorElement: , }, + { + path: paths.mentors, + element: , + }, ]) const queryClient = new QueryClient() diff --git a/web/usuaris/src/pages/Home.tsx b/web/usuaris/src/pages/Home.tsx index 3b3e7501d..dc2158032 100644 --- a/web/usuaris/src/pages/Home.tsx +++ b/web/usuaris/src/pages/Home.tsx @@ -1,20 +1,8 @@ -import { FC, useEffect, useState } from 'react' +import { FC } from 'react' import styled from 'styled-components' import { FlexBox, colors, dimensions } from '@itacademy/ui' -import { - FiltersWidget, - Login, - Navbar, - SideMenu, - UsersTable, -} from '../components/organisms' +import { Dashboard, Login, Navbar } from '../components/organisms' import { useAuth } from '../context/AuthProvider' -import { TFilters, TUpdatedUsersStatus, UserStatus } from '../types' -import { - ActionsDropdown, - DeleteConfirmationModal, -} from '../components/molecules' -import { useUpdateUsersStatus } from '../hooks' const Container = styled(FlexBox)` width: 100%; @@ -24,24 +12,6 @@ const Container = styled(FlexBox)` ${dimensions.spacing.xl} ${dimensions.spacing.sm}; ` -const ContainerMain = styled(FlexBox)` - width: 100%; - height: 100%; -` - -const MainDiv = styled(FlexBox)` - background-color: ${colors.white}; - width: 100%; - height: 100%; - padding: ${dimensions.spacing.lg} ${dimensions.spacing.xxxl}; - border-radius: ${dimensions.borderRadius.base}; - color: ${colors.gray.gray3}; -` - -const ContainerFiltersActions = styled(FlexBox)` - width: 100%; -` - const LoginContainer = styled(FlexBox)` width: 50%; height: auto; @@ -52,39 +22,6 @@ const LoginContainer = styled(FlexBox)` export const Home: FC = () => { const { user } = useAuth() - const { changeUsersStatus, isSuccess: statusSuccess } = useUpdateUsersStatus() - - const [filters, setFilters] = useState({}) - const [selectedStatus, setSelectedStatus] = useState( - undefined - ) - const [selectedUsers, setSelectedUsers] = useState([]) - const [isActionFinished, setIsActionFinished] = useState(false) - const [isModalOpen, setIsModalOpen] = useState(false) - - const handleSelectedUsers = (users: string[]) => { - setSelectedUsers(users) - } - - const handleAction = (action: string | undefined) => { - setIsActionFinished(false) - if (action && action !== 'DELETE') { - const updatedUsersStatus: TUpdatedUsersStatus = { - ids: selectedUsers, - status: action, - } - changeUsersStatus.mutate(updatedUsersStatus) - } else { - setIsModalOpen(!isModalOpen) - } - } - - useEffect(() => { - if (statusSuccess) { - setSelectedStatus(undefined) - setIsActionFinished(true) - } - }, [statusSuccess]) if (!user) return ( @@ -102,48 +39,8 @@ export const Home: FC = () => { ) return ( - <> - - - - - - - - - - - - - - { - setIsModalOpen(false) - setSelectedStatus(undefined) - setIsActionFinished(true) - }} - idsToDelete={selectedUsers} - /> - +
+ +
) } diff --git a/web/usuaris/src/pages/Mentors.tsx b/web/usuaris/src/pages/Mentors.tsx new file mode 100644 index 000000000..a9ea54900 --- /dev/null +++ b/web/usuaris/src/pages/Mentors.tsx @@ -0,0 +1,19 @@ +import { FC } from 'react' +import { Navigate } from 'react-router-dom' +import { Dashboard } from '../components/organisms' +import { useAuth } from '../context/AuthProvider' +import { paths } from '../constants' + +export const Mentors: FC = () => { + const { user } = useAuth() + + if (!user) { + return + } + + return ( +
+ +
+ ) +} diff --git a/web/usuaris/src/pages/index.ts b/web/usuaris/src/pages/index.ts index eec13c60a..b6e304c0e 100644 --- a/web/usuaris/src/pages/index.ts +++ b/web/usuaris/src/pages/index.ts @@ -1,2 +1,3 @@ export { ErrorPage } from './ErrorPage' export { Home } from './Home' +export { Mentors } from './Mentors' diff --git a/web/usuaris/src/types/index.tsx b/web/usuaris/src/types/index.tsx index 77631dbae..0187d6539 100644 --- a/web/usuaris/src/types/index.tsx +++ b/web/usuaris/src/types/index.tsx @@ -1,6 +1,8 @@ +export { UserRole } from './types' export { UserStatus } from './types' export { type TFilters } from './types' export { type TItinerary } from './types' +export { type TRole } from './types' export { type TUpdatedUser } from './types' export { type TUpdatedUsersStatus } from './types' export { type TUserData } from './types'