Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #54 - Centres dropdown on Students table #76

Merged
merged 4 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -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
23 changes: 23 additions & 0 deletions src/components/CentresDropdown/CentresDropdown.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { SxProps, Theme } from '@mui/material/styles'

export const selectButtonStyle: SxProps<Theme> = {
borderRadius: '15px',
width: '300px'
}

export const selectIconStyle: SxProps<Theme> = {
marginRight: '10px'
}

export const selectMenuStyle = {
display: 'flex',
alignItems: 'center'
}

const allStyles = {
selectButtonStyle,
selectIconStyle,
selectMenuStyle
}

export default allStyles
69 changes: 69 additions & 0 deletions src/components/CentresDropdown/CentresDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
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 { useSession } from 'next-auth/react'
import { useEffect, useState } from 'react'

import {
selectButtonStyle,
selectIconStyle,
selectMenuStyle
} from './CentresDropdown.styled'

import { getCentresList } from '@/lib/centres/centres-client'
import { Centre } from '@/types/centre.type'

const ALL_CENTRES: Centre = {
id: 0,
name: 'All Centres',
organization_id: null,
address: null
}

export default function CentresDropdown({
value,
onChange
}: {
value: Number
onChange: Function
}) {
const { data: session } = useSession()
const [centres, setCentres] = useState<Array<Centre>>([ALL_CENTRES])

useEffect(() => {
const orgId: string | null = session?.user?.organization.id ?? null
if (orgId && centres.length < 2) {
getCentresList(orgId).then((list: Array<Centre>) =>
setCentres(list.concat([ALL_CENTRES]))
)
}
}, [centres, session])

const handleChange = (event: SelectChangeEvent<Number>) => {
onChange(Number(event.target.value))
}

const centreMenuItems = [ALL_CENTRES].concat(centres).map((item) => {
const selected = item.id === value
const visibilityStyle = selected ? { display: 'none' } : {}

return (
<MenuItem value={item.id} style={visibilityStyle} key={item.id}>
<div style={selectMenuStyle}>
{selected && <ApartmentIcon sx={selectIconStyle} />}
<div>{item.name}</div>
</div>
</MenuItem>
)
})

return (
<FormControl size="small">
<Select value={value} onChange={handleChange} sx={selectButtonStyle}>
{centreMenuItems}
</Select>
</FormControl>
)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import styled from '@emotion/styled'

import Button from '../Button/Button'

export const TestimonialTrigger = styled(Button)(({ theme }) => ({
Expand Down
4 changes: 3 additions & 1 deletion src/components/TestimonialPopup/TestimonialPopup.tsx
Original file line number Diff line number Diff line change
@@ -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
Expand Down
5 changes: 5 additions & 0 deletions src/lib/centres/centres-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { client } from '../api-client'

export function getCentresList(orgId: string | number) {
return client(`organizations/${orgId}/centres/`)
}
50 changes: 7 additions & 43 deletions src/pages/app/students.tsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,26 @@
import ApartmentIcon from '@mui/icons-material/Apartment'
import Box from '@mui/material/Box'
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 { NextPage } from 'next/types'
import { useState } 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'
import { WithAuthentication } from '@/types/with-authentication/with-authentication.type'

// 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' }
]

const StudentsPage: WithAuthentication<NextPage> = () => {
const [searchInput, setSearchInput] = useState('')
const [searchCheckboxes, setSearchCheckboxes] = useState([true, false, false])
const [center, setCenter] = useState<number>(0)
const [centre, setCentre] = useState<number>(0)

const handleCenterChange = (event: SelectChangeEvent<number>) => {
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 (
<MenuItem value={item.id} style={visibilityStyle} key={item.id}>
<div style={selectMenuStyle}>
{selected && <ApartmentIcon sx={selectIconStyle} />}
<div>{item.label}</div>
</div>
</MenuItem>
)
})

const handleSearchInputChange = (
event: React.ChangeEvent<HTMLInputElement>
) => {
Expand All @@ -75,15 +47,7 @@ const StudentsPage: WithAuthentication<NextPage> = () => {
<div>Students Page</div>

<Box sx={flexContainer}>
<FormControl size="small">
<Select
value={center}
onChange={handleCenterChange}
sx={selectButtonStyle}
>
{centerMenuItems}
</Select>
</FormControl>
<CentresDropdown value={centre} onChange={handleCentreChange} />

<Box sx={filterLeftMargin}>
<InputWithCheckboxes
Expand Down
19 changes: 1 addition & 18 deletions src/styles/pages/app/students.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,9 @@ export const flexContainer: SxProps<Theme> = {
display: 'flex'
}

export const selectButtonStyle: SxProps<Theme> = {
borderRadius: '15px',
width: '300px'
}

export const selectIconStyle: SxProps<Theme> = {
marginRight: '10px'
}

export const selectMenuStyle = {
display: 'flex',
alignItems: 'center'
}

const allStyles = {
filterLeftMargin,
flexContainer,
selectButtonStyle,
selectIconStyle,
selectMenuStyle
flexContainer
}

export default allStyles
6 changes: 6 additions & 0 deletions src/types/centre.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface Centre {
id: number
name: string
organization_id: number | null
address: string | null
}