Skip to content

Commit

Permalink
Merge pull request #74 from LamArt/feature/SCHOOL-726/circle-page
Browse files Browse the repository at this point in the history
circle page
  • Loading branch information
levil664 authored Aug 31, 2023
2 parents a5b58d8 + 13200b3 commit d53636e
Show file tree
Hide file tree
Showing 15 changed files with 263 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const searchStudentsColumns = ['name', 'address']
86 changes: 86 additions & 0 deletions apps/schools/domains/circle/components/studentList/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import React, { useState } from 'react'
import { Typography } from 'antd'
import router from 'next/router'
import styles from './styles/styles.module.scss'
import { useOrganization } from '@domains/organization/providers/organizationProvider'
import { Button } from '@domains/common/components/button'
import { Table } from '@domains/common/components/table'
import { createSearchTextForRequest } from '@domains/common/utils/searchText'
import { RowType, TableType } from './interfaces'
import { searchStudentsColumns } from './constants'
import { useGetAllCirclesQuery } from '@domains/organization/redux/organizationApi'
import EmptyWrapper from '@domains/common/components/containers/EmptyWrapper'
import { mapReturnedData } from '@domains/common/redux/utils'
import { HighlightText } from '@domains/common/components/table/forming'
import { getVarsForAddressColumn } from '@domains/student/components/studentList/utils'

export function CircleList() {
const [searchRequestText, setSearchRequestText] = useState('')
const { organizationId } = useOrganization()

const { data: circles, isLoading: isLoading } = useGetAllCirclesQuery({
organization_id: organizationId,
or_search: createSearchTextForRequest(searchRequestText, searchStudentsColumns),
})

const reformattedData = mapReturnedData(circles, (circle) => {
const transformedCircle = structuredClone(circle) as TableType
transformedCircle.accepted_count = circle.student_profile_queries.ACCEPTED
return transformedCircle
})

return (
<EmptyWrapper
titleText={'Список кружков пока пуст'}
descriptionText={'Вы можете добавить их, нажав на кнопку'}
buttonText={'Добавить кружок'}
pageTitle={'Кружки'}
data={circles}
isLoading={isLoading}
handleRunTask={() => router.push('/circle/create')}
searchTrigger={searchRequestText}
>
<div className={styles.header}>
<Typography.Title level={1}>Кружки</Typography.Title>
<Button
type='schoolDefault'
block
className={styles.button}
onClick={() => router.push('/circle/create')}
>
Добавить кружок
</Button>
</div>
<Table<RowType, TableType>
columnsTitlesAndKeys={[
['Название', 'name'],
['Адрес', 'address'],
['Кол-во принятых заявок', 'accepted_count'],
]}
data={reformattedData}
isLoading={isLoading}
mainRoute={'/student'}
searchFields={['name', 'address']}
customFields={{
address: ({ text, searchText }) => {
const [address, additional_text] = getVarsForAddressColumn(text ?? '')

return (
<div>
<div className={styles.additionalTextAddress}>
<HighlightText text={additional_text ?? ''} searchText={searchText} />
</div>

<div className={styles.textAddress}>
<HighlightText text={address ?? ''} searchText={searchText} />
</div>
</div>
)
},
}}
searchRequestText={searchRequestText}
setSearchRequestText={setSearchRequestText}
/>
</EmptyWrapper>
)
}
13 changes: 13 additions & 0 deletions apps/schools/domains/circle/components/studentList/interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export interface RowType {
id?: string
name: string
address: string
accepted_count: number
}

export interface TableType {
id?: string
name: string
address: string
accepted_count: number
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
@import '../../../../common/components/styles/abstracts/common';

.tableContainer {
@extend %table;
}

.header {
margin-bottom: 31px;
align-items: center;
display: flex;
flex-direction: row;
justify-content: space-between;

.button {
min-width: 200px;
text-align: center;
font-family: 'Roboto', sans-serif;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: 24px;
width: 14%;
}
}

.search {
font-size: 150%;
position: absolute;
right: 30px;
}

.cross {
font-size: 100%;
position: absolute;
right: 60px;

:hover {
opacity: .6;
}

:active, :focus {
opacity: .8;
}
}

.additionalTextAddress {
color: $color-background;
font-family: 'Roboto', sans-serif;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: 22px;
}

.textAddress {
color: $color-foreground;
font-family: 'Roboto', sans-serif;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 22px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ const menuList: MenuItemObj[] = [
isOrganizationSelected,
permanentDisabled,
]),
new MenuItemObj('circles', 'Кружки', <ReadOutlined style={{ fontSize: '150%' }} />, [
isOrganizationSelected,
permanentDisabled,
]),
new MenuItemObj('circle', 'Кружки', <ReadOutlined style={{ fontSize: '150%' }} />, [isOrganizationSelected]),
new MenuItemObj('student', 'Обучающиеся', <TeamOutlined style={{ fontSize: '150%' }} />, [isOrganizationSelected]),
new MenuItemObj('queries', 'Заявки', <FileDoneOutlined style={{ fontSize: '150%' }} />, [
isOrganizationSelected,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,5 @@ $color-selected-organization: #434343;
$color-border-table: #D0D3E5;
$color-header-table: #F2F3F7;
$color-search-highlight-text: #ffc95f;
$color-background: #434343;
$color-foreground: rgba(67, 67, 67, 0.80);
9 changes: 6 additions & 3 deletions apps/schools/domains/common/components/table/forming.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ColumnType } from 'antd/lib/table/interface'
import React from 'react'
import styles from './styles/styles.module.scss'
import { getSearchText } from '@domains/common/utils/searchText'
import { HighlightTextProps } from '@domains/common/components/table/interfaces'
import { CustomFieldsProps, HighlightTextProps } from '@domains/common/components/table/interfaces'
import { filterTextShaper } from '@domains/common/utils/filterTextShaper'

export interface RawColumnType<RowType> extends ColumnType<RowType> {
Expand Down Expand Up @@ -52,7 +52,7 @@ function escapeRegExp(text: string) {
return text.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&')
}

function HighlightText({ text, searchText }: HighlightTextProps) {
export function HighlightText({ text, searchText }: HighlightTextProps) {
const isMatch = text.toLowerCase().includes(searchText.toLowerCase())

if (isMatch) {
Expand Down Expand Up @@ -81,14 +81,17 @@ export function objectReBuilder<DataItemType>(
fields: string[],
searchFields: string[],
searchRequestText: string,
customFields: CustomFieldsProps,
needId: boolean,
): Array<Object> {
let resultArray: Array<Object> = []
const searchText = getSearchText(searchRequestText)
data.forEach((item: any) => {
const newItem: any = {}
for (const field of fields) {
if (searchFields.includes(field))
if (field in customFields) {
newItem[field] = customFields[field]({ text: item[field], searchText: searchText })
} else if (searchFields.includes(field))
newItem[field] = <HighlightText text={item[field] ?? ''} searchText={searchText} />
else newItem[field] = item[field]
}
Expand Down
2 changes: 2 additions & 0 deletions apps/schools/domains/common/components/table/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { calculateAverageWidth } from '@domains/common/utils/calculateAverageWid
export const Table = <RowType, DataItemType>(props: CustomTableProps<RowType, DataItemType>) => {
const {
customType = 'tableWithSearch',
customFields = {},
filterFields,
columnsTitlesAndKeys,
data,
Expand Down Expand Up @@ -42,6 +43,7 @@ export const Table = <RowType, DataItemType>(props: CustomTableProps<RowType, Da
columnsTitlesAndKeys.map((x) => x[1]),
searchFields,
searchRequestText,
customFields,
true,
)
setDataSource(result)
Expand Down
11 changes: 10 additions & 1 deletion apps/schools/domains/common/components/table/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
import React from 'react'
import { ReturnedData } from '@domains/common/redux/interfaces'
import { TableProps } from 'antd'

export interface CustomTableProps<RowType, DataItemType> {
export interface CustomFieldsProps {
[key: string]: React.FC<{
text: string
searchText: string
}>
}

export interface CustomTableProps<RowType, DataItemType> extends TableProps<any> {
customType?: 'tableWithSearch' | 'tableWithoutSearch'
columnsTitlesAndKeys: Array<string[]>
filterFields?: string[]
data?: ReturnedData<DataItemType[]>
isLoading: boolean
searchFields: string[]
customFields?: CustomFieldsProps
searchRequestText: string
setSearchRequestText: React.Dispatch<React.SetStateAction<string>>
mainRoute: string
Expand Down
12 changes: 12 additions & 0 deletions apps/schools/domains/common/redux/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ReturnedData } from '@domains/common/redux/interfaces'

export function mapReturnedData<T>(response: ReturnedData<T[]> | undefined, delegate: (x: T) => any) {
return response !== undefined
? ({
count: response.count,
next: response.next,
previous: response.previous,
results: response.results.map(delegate),
} as ReturnedData<any>)
: undefined
}
26 changes: 26 additions & 0 deletions apps/schools/domains/organization/redux/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BasePaginationData } from '../../common/redux/interfaces'
import { GetAnalytics } from '@domains/common/redux/serializers'

export interface AllOrganizationsData extends BasePaginationData {
id?: string
Expand Down Expand Up @@ -89,3 +90,28 @@ export interface getAllStudentInvitationsData extends BasePaginationData {
student__id?: string
student__name?: string
}

export interface GetOrganizationCircleList {
id?: string
name: string
address: string
student_profile_queries: GetAnalytics
}

export interface GetOrganizationCircleListData extends BasePaginationData {
id?: string
organization?: string
organization__id?: string
organization_id?: string
capacity?: number
description?: string
ids?: string
or_search?: string
address?: string
organization_name?: string
radius?: string
user_location?: string
student_profile?: string
name?: string
order?: string
}
10 changes: 10 additions & 0 deletions apps/schools/domains/organization/redux/organizationApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
AllTeachersData,
AllQueriesOfOrganizationData,
getAllStudentInvitationsData,
GetOrganizationCircleList,
GetOrganizationCircleListData,
} from './interfaces'
import { GetEmployee } from '../../employee/redux/interfaces'
import {
Expand Down Expand Up @@ -69,6 +71,13 @@ const organizationApi = commonApi.injectEndpoints({
params: params,
}),
}),
getAllCircles: build.query<ReturnedData<GetOrganizationCircleList[]>, GetOrganizationCircleListData>({
query: (params) => ({
url: `/organization-management/organizations/${params.organization_id}/circles`,
method: 'GET',
params: params,
}),
}),
getStudent: build.query<{ student: GetStudent }, StudentData>({
query: (data) => ({
url: `/organization-management/organizations/students/${data.student_id}`,
Expand Down Expand Up @@ -158,4 +167,5 @@ export const {
useGetAllTeachersQuery,
useGetAllQueriesOfOrganizationQuery,
useGetAllStudentInvitationsQuery,
useGetAllCirclesQuery,
} = organizationApi
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export const searchInvitesColumns = ['student__name', 'student_profile__phone', 'family__parent_phone', 'circle__name']
export const searchStudentsColumns = ['name', 'student_profile__phone', 'parent_phone', 'circle__name']

export const ADDRESS_SEPARATOR = '&;'
5 changes: 5 additions & 0 deletions apps/schools/domains/student/components/studentList/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ADDRESS_SEPARATOR } from '@domains/student/components/studentList/constants'

export function getVarsForAddressColumn(text: string) {
return text.split(ADDRESS_SEPARATOR)
}
25 changes: 25 additions & 0 deletions apps/schools/pages/circle/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react'
import Head from 'next/head'
import { PageContent } from '@domains/common/components/containers/PageContent'

import {
OrganizationRequired,
} from '@domains/common/components/containers/OrganizationRequired'
import {CircleList} from "@domains/circle/components/studentList";

const CirclesPageContent = () => {
return (
<>
<Head>
<title>Кружки</title>
</Head>
<PageContent>
<OrganizationRequired>
<CircleList/>
</OrganizationRequired>
</PageContent>
</>
)
}

export default CirclesPageContent

0 comments on commit d53636e

Please sign in to comment.