From 1e7b160652144cab4ce9ad3a01b59676bbf3b98d Mon Sep 17 00:00:00 2001 From: Jose Date: Thu, 31 Aug 2023 17:40:38 -0300 Subject: [PATCH 1/3] feat: implement component for Centres dropdown (issue #54) --- .../CentresDropdown/CentresDropdown.styled.ts | 23 ++++++++ .../CentresDropdown/CentresDropdown.tsx | 57 +++++++++++++++++++ .../TestimonialPopup.styled.ts | 1 + .../TestimonialPopup/TestimonialPopup.tsx | 4 +- src/pages/app/students.tsx | 51 +++-------------- src/styles/pages/app/students.styled.ts | 19 +------ 6 files changed, 92 insertions(+), 63 deletions(-) create mode 100644 src/components/CentresDropdown/CentresDropdown.styled.ts create mode 100644 src/components/CentresDropdown/CentresDropdown.tsx diff --git a/src/components/CentresDropdown/CentresDropdown.styled.ts b/src/components/CentresDropdown/CentresDropdown.styled.ts new file mode 100644 index 0000000..8348f9b --- /dev/null +++ b/src/components/CentresDropdown/CentresDropdown.styled.ts @@ -0,0 +1,23 @@ +import { SxProps, Theme } from '@mui/material/styles' + +export const selectButtonStyle: SxProps = { + borderRadius: '15px', + width: '300px' +} + +export const selectIconStyle: SxProps = { + marginRight: '10px' +} + +export const selectMenuStyle = { + display: 'flex', + alignItems: 'center' +} + +const allStyles = { + selectButtonStyle, + selectIconStyle, + selectMenuStyle +} + +export default allStyles diff --git a/src/components/CentresDropdown/CentresDropdown.tsx b/src/components/CentresDropdown/CentresDropdown.tsx new file mode 100644 index 0000000..1f35c4b --- /dev/null +++ b/src/components/CentresDropdown/CentresDropdown.tsx @@ -0,0 +1,57 @@ +import ApartmentIcon from '@mui/icons-material/Apartment' +import FormControl from '@mui/material/FormControl' +import MenuItem from '@mui/material/MenuItem' +import Select from '@mui/material/Select' +import { SelectChangeEvent } from '@mui/material/Select' +import { useState } from 'react' + +import { + selectButtonStyle, + selectIconStyle, + selectMenuStyle +} from './CentresDropdown.styled' + +const DUMMY_DATA = [1, 2, 3].map((number) => ({ + id: number, + name: `Centre ${number}`, + organization_id: number, + address: `Fake street ${number * 5}` +})) + +const ALL_CENTRES = { id: 0, name: 'All Centres' } + +export default function CentresDropdown({ + value, + onChange +}: { + value: Number + onChange: Function +}) { + const [centres, setCentres] = useState(DUMMY_DATA) + + const handleChange = (event: SelectChangeEvent) => { + onChange(Number(event.target.value)) + } + + const centreMenuItems = [ALL_CENTRES].concat(centres).map((item) => { + const selected = item.id === value + const visibilityStyle = selected ? { display: 'none' } : {} + + return ( + +
+ {selected && } +
{item.name}
+
+
+ ) + }) + + return ( + + + + ) +} diff --git a/src/components/TestimonialPopup/TestimonialPopup.styled.ts b/src/components/TestimonialPopup/TestimonialPopup.styled.ts index a5f102b..3dca8a7 100644 --- a/src/components/TestimonialPopup/TestimonialPopup.styled.ts +++ b/src/components/TestimonialPopup/TestimonialPopup.styled.ts @@ -1,4 +1,5 @@ import styled from '@emotion/styled' + import Button from '../Button/Button' export const TestimonialTrigger = styled(Button)(({ theme }) => ({ diff --git a/src/components/TestimonialPopup/TestimonialPopup.tsx b/src/components/TestimonialPopup/TestimonialPopup.tsx index 2a6af48..0dd87c5 100644 --- a/src/components/TestimonialPopup/TestimonialPopup.tsx +++ b/src/components/TestimonialPopup/TestimonialPopup.tsx @@ -1,11 +1,13 @@ // components +import YouTubeIcon from '@mui/icons-material/YouTube' + import Popup from '../Popup/Popup' + import { TestimonialTrigger, TestimonialVideo, VideoWrapper } from './TestimonialPopup.styled' -import YouTubeIcon from '@mui/icons-material/YouTube' interface TestimonialPopupProps { title: string diff --git a/src/pages/app/students.tsx b/src/pages/app/students.tsx index 30d6914..3aa582e 100644 --- a/src/pages/app/students.tsx +++ b/src/pages/app/students.tsx @@ -1,30 +1,14 @@ -import ApartmentIcon from '@mui/icons-material/Apartment' import Box from '@mui/material/Box' -import FormControl from '@mui/material/FormControl' -import FormHelperText from '@mui/material/FormHelperText' -import MenuItem from '@mui/material/MenuItem' -import Select from '@mui/material/Select' -import { SelectChangeEvent } from '@mui/material/Select' import * as React from 'react' +import CentresDropdown from '@/components/CentresDropdown/CentresDropdown' import InputWithCheckboxes from '@/components/Input/InputWithCheckboxes/InputWithCheckboxes' import { DashboardLayout } from '@/containers/dashboard/DashboardLayout' import { filterLeftMargin, - flexContainer, - selectButtonStyle, - selectIconStyle, - selectMenuStyle + flexContainer } from '@/styles/pages/app/students.styled' -// TODO (#54): Use real data to populate the dropdown. -const items = [ - { id: 0, label: 'All centers' }, - { id: 1, label: 'Center A' }, - { id: 2, label: 'Center B' }, - { id: 3, label: 'Center C' } -] - export default function StudentsPage() { const [searchInput, setSearchInput] = React.useState('') const [searchCheckboxes, setSearchCheckboxes] = React.useState([ @@ -32,26 +16,13 @@ export default function StudentsPage() { false, false ]) - const [center, setCenter] = React.useState(0) + const [centre, setCentre] = React.useState(0) - const handleCenterChange = (event: SelectChangeEvent) => { - setCenter(Number(event.target.value)) + const handleCentreChange = (newCentre: number) => { + setCentre(newCentre) + // TODO: Should trigger search. } - const centerMenuItems = items.map((item) => { - const selected = item.id === center - const visibilityStyle = selected ? { display: 'none' } : {} - - return ( - -
- {selected && } -
{item.label}
-
-
- ) - }) - const handleSearchInputChange = ( event: React.ChangeEvent ) => { @@ -78,15 +49,7 @@ export default function StudentsPage() {
Students Page
- - - + = { display: 'flex' } -export const selectButtonStyle: SxProps = { - borderRadius: '15px', - width: '300px' -} - -export const selectIconStyle: SxProps = { - marginRight: '10px' -} - -export const selectMenuStyle = { - display: 'flex', - alignItems: 'center' -} - const allStyles = { filterLeftMargin, - flexContainer, - selectButtonStyle, - selectIconStyle, - selectMenuStyle + flexContainer } export default allStyles From 0ffcc34a61cf39736bb51724ef88d843e0aa56b8 Mon Sep 17 00:00:00 2001 From: Jose Date: Mon, 11 Sep 2023 18:24:40 -0300 Subject: [PATCH 2/3] feat: minor fix on .env file (issue #54) --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 3a4306a..90620fe 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,3 @@ -NEXT_PUBLIC_API_URL=http://localhost:3000/api +NEXT_PUBLIC_API_URL=http://localhost:3000/api/v1 NEXTAUTH_URL=http://localhost:3000 NEXTAUTH_SECRET=secret \ No newline at end of file From 74f0474e0db52407c6a474eb1eaa9ac5800874f0 Mon Sep 17 00:00:00 2001 From: Jose Date: Thu, 14 Sep 2023 16:08:49 -0300 Subject: [PATCH 3/3] feat: fetch list of available Centres from backend (issue #54) --- .../CentresDropdown/CentresDropdown.tsx | 30 +++++++++++++------ src/lib/centres/centres-client.ts | 5 ++++ src/types/centre.type.ts | 6 ++++ 3 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 src/lib/centres/centres-client.ts create mode 100644 src/types/centre.type.ts diff --git a/src/components/CentresDropdown/CentresDropdown.tsx b/src/components/CentresDropdown/CentresDropdown.tsx index 1f35c4b..8f7516c 100644 --- a/src/components/CentresDropdown/CentresDropdown.tsx +++ b/src/components/CentresDropdown/CentresDropdown.tsx @@ -3,7 +3,8 @@ import FormControl from '@mui/material/FormControl' import MenuItem from '@mui/material/MenuItem' import Select from '@mui/material/Select' import { SelectChangeEvent } from '@mui/material/Select' -import { useState } from 'react' +import { useSession } from 'next-auth/react' +import { useEffect, useState } from 'react' import { selectButtonStyle, @@ -11,14 +12,15 @@ import { selectMenuStyle } from './CentresDropdown.styled' -const DUMMY_DATA = [1, 2, 3].map((number) => ({ - id: number, - name: `Centre ${number}`, - organization_id: number, - address: `Fake street ${number * 5}` -})) +import { getCentresList } from '@/lib/centres/centres-client' +import { Centre } from '@/types/centre.type' -const ALL_CENTRES = { id: 0, name: 'All Centres' } +const ALL_CENTRES: Centre = { + id: 0, + name: 'All Centres', + organization_id: null, + address: null +} export default function CentresDropdown({ value, @@ -27,7 +29,17 @@ export default function CentresDropdown({ value: Number onChange: Function }) { - const [centres, setCentres] = useState(DUMMY_DATA) + const { data: session } = useSession() + const [centres, setCentres] = useState>([ALL_CENTRES]) + + useEffect(() => { + const orgId: string | null = session?.user?.organization.id ?? null + if (orgId && centres.length < 2) { + getCentresList(orgId).then((list: Array) => + setCentres(list.concat([ALL_CENTRES])) + ) + } + }, [centres, session]) const handleChange = (event: SelectChangeEvent) => { onChange(Number(event.target.value)) diff --git a/src/lib/centres/centres-client.ts b/src/lib/centres/centres-client.ts new file mode 100644 index 0000000..8f19b2b --- /dev/null +++ b/src/lib/centres/centres-client.ts @@ -0,0 +1,5 @@ +import { client } from '../api-client' + +export function getCentresList(orgId: string | number) { + return client(`organizations/${orgId}/centres/`) +} diff --git a/src/types/centre.type.ts b/src/types/centre.type.ts new file mode 100644 index 0000000..f043573 --- /dev/null +++ b/src/types/centre.type.ts @@ -0,0 +1,6 @@ +export interface Centre { + id: number + name: string + organization_id: number | null + address: string | null +}