diff --git a/apps/schools/domains/circle/components/currentCircle/index.tsx b/apps/schools/domains/circle/components/currentCircle/index.tsx index 29539644..e1dffb62 100644 --- a/apps/schools/domains/circle/components/currentCircle/index.tsx +++ b/apps/schools/domains/circle/components/currentCircle/index.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react' -import router, { useRouter } from 'next/router' +import { useRouter } from 'next/router' import { Col, Row, Typography } from 'antd' import Image from 'next/image' import Link from 'next/link' @@ -23,7 +23,7 @@ import { searchColumns } from './constants' import { CurrentCircleRowType } from './interfaces' import styles from './styles/styles.module.scss' import { getVarsForAddressColumn } from '@domains/common/utils/geo' -import { QueryStatuses } from '@domains/common/constants/Enums' +import { StatusesEnum } from '@domains/common/constants/Enums' import { ErrorType } from '@store/commonApi' import { AppRoutes, RoutePath } from '@domains/common/constants/routerEnums' @@ -98,7 +98,7 @@ const CurrentCircle = () => {
Принято
{queriesCount.ACCEPTED} @@ -108,7 +108,7 @@ const CurrentCircle = () => {
На рассмотрении
{queriesCount.IN_PROGRESS} diff --git a/apps/schools/domains/common/components/bubbleFilter/styles/styles.module.scss b/apps/schools/domains/common/components/bubbleFilter/styles/styles.module.scss index 50e137a3..d680d6d9 100644 --- a/apps/schools/domains/common/components/bubbleFilter/styles/styles.module.scss +++ b/apps/schools/domains/common/components/bubbleFilter/styles/styles.module.scss @@ -6,7 +6,6 @@ align-items: center; margin-bottom: 20px; gap: 10px; - cursor: pointer; .text { font-family: "Open Sans", sans-serif; @@ -22,6 +21,7 @@ padding: 7px 10px 7px 5px; border: 1px solid #D9D9D9; border-radius: 20px; + cursor: pointer; &:hover { background-color: #f1f1f1; diff --git a/apps/schools/domains/common/components/containers/BaseLayoutComponents/BaseLayout/index.tsx b/apps/schools/domains/common/components/containers/BaseLayoutComponents/BaseLayout/index.tsx index 11b4bfe1..b8a86ac8 100644 --- a/apps/schools/domains/common/components/containers/BaseLayoutComponents/BaseLayout/index.tsx +++ b/apps/schools/domains/common/components/containers/BaseLayoutComponents/BaseLayout/index.tsx @@ -12,7 +12,7 @@ import { IBaseLayoutProps } from './interfaces' import { OrganizationSelect } from '../OrganizationSelect' import { useLayoutContext } from '@domains/user/providers/baseLayoutProvider' import { COLLAPSED_DIVIDER_WIDTH, COLLAPSED_LAYOUT_WIDTH, DIVIDER_WIDTH, LAYOUT_WIDTH } from './styles/styles' -import { QueryStatuses } from '@domains/common/constants/Enums' +import { StatusesEnum } from '@domains/common/constants/Enums' import Image from 'next/image' import ExclamationCircleOutlined from '@public/icons/ExclamationCircleOutlined.svg' import { Button } from '@domains/common/components/button' @@ -36,7 +36,7 @@ export const BaseLayout: React.FC = (props) => {
{invitations?.results.map((invite) => { - if (invite.status === QueryStatuses.SENT || invite.status === QueryStatuses.IN_PROGRESS) { + if (invite.status === StatusesEnum.SENT || invite.status === StatusesEnum.IN_PROGRESS) { return (
@@ -50,7 +50,7 @@ export const BaseLayout: React.FC = (props) => { handleChangeStatusInvitation( mutation, invite.id, - QueryStatuses.ACCEPTED, + StatusesEnum.ACCEPTED, ).then(() => { refetch() emit(EventKey.RefetchOrganizationsQuery) @@ -65,7 +65,7 @@ export const BaseLayout: React.FC = (props) => { handleChangeStatusInvitation( mutation, invite.id, - QueryStatuses.DECLINED, + StatusesEnum.DECLINED, ).then(refetch) } > diff --git a/apps/schools/domains/common/components/containers/BaseLayoutComponents/Menu/index.tsx b/apps/schools/domains/common/components/containers/BaseLayoutComponents/Menu/index.tsx index f94fa5cb..cedc8ad1 100644 --- a/apps/schools/domains/common/components/containers/BaseLayoutComponents/Menu/index.tsx +++ b/apps/schools/domains/common/components/containers/BaseLayoutComponents/Menu/index.tsx @@ -1,5 +1,5 @@ import { Menu } from 'antd' -import { FileDoneOutlined, ReadOutlined, TeamOutlined, UserAddOutlined } from '@ant-design/icons' +import { FileDoneOutlined, MailOutlined, ReadOutlined, TeamOutlined, UserAddOutlined } from '@ant-design/icons' import React, { useEffect, useState } from 'react' import { useRouter } from 'next/router' import styles from './styles/styles.module.scss' @@ -15,6 +15,7 @@ const menuList: MenuItemObj[] = [ new MenuItemObj('employee', 'Сотрудники', , [ isOrganizationSelected, ]), + new MenuItemObj('ticket', 'Обращения', , [isOrganizationSelected]), ] const MenuCustom = () => { diff --git a/apps/schools/domains/common/constants/Enums.ts b/apps/schools/domains/common/constants/Enums.ts index da755dd3..41623b3f 100644 --- a/apps/schools/domains/common/constants/Enums.ts +++ b/apps/schools/domains/common/constants/Enums.ts @@ -1,4 +1,4 @@ -export enum QueryStatuses { +export enum StatusesEnum { SENT = 'SENT', ACCEPTED = 'ACCEPTED', IN_PROGRESS = 'IN_PROGRESS', diff --git a/apps/schools/domains/common/constants/routerEnums.ts b/apps/schools/domains/common/constants/routerEnums.ts index 8f14da78..07b2e0a2 100644 --- a/apps/schools/domains/common/constants/routerEnums.ts +++ b/apps/schools/domains/common/constants/routerEnums.ts @@ -9,6 +9,7 @@ export const enum AppRoutes { EMPLOYEE_CREATE = 'employee_create', MAIN = 'main', MOBILE_RECAPTCHA = 'mobile_recaptcha', + TICKETS_LIST = 'tickets_list', NOT_FOUND = 'not_found', QUERY_LIST = 'query_list', STUDENT_LIST = 'student_list', @@ -28,6 +29,7 @@ export const RoutePath: Record = { [AppRoutes.EMPLOYEE_CREATE]: '/employee/create', [AppRoutes.MAIN]: '/', [AppRoutes.MOBILE_RECAPTCHA]: '/mobile-recaptcha', + [AppRoutes.TICKETS_LIST]: '/ticket', [AppRoutes.NOT_FOUND]: '/404', [AppRoutes.QUERY_LIST]: '/query', [AppRoutes.STUDENT_LIST]: '/student', diff --git a/apps/schools/domains/common/handlers/changeStatusInvitation.ts b/apps/schools/domains/common/handlers/changeStatusInvitation.ts index 2c5d9b56..8754fb8b 100644 --- a/apps/schools/domains/common/handlers/changeStatusInvitation.ts +++ b/apps/schools/domains/common/handlers/changeStatusInvitation.ts @@ -2,7 +2,7 @@ import { withLoadingMessage } from '@domains/common/utils/loading' import { LoadingMsg } from '@domains/user/components/auth/constants/message' import { message } from 'antd' import { QueriesTypes } from '@domains/common/redux/interfaces' -import { QueryStatuses } from '@domains/common/constants/Enums' +import { StatusesEnum } from '@domains/common/constants/Enums' export async function handleChangeStatusInvitation(mutation: any, id: string | undefined, status: QueriesTypes) { if (id === undefined) { @@ -16,7 +16,7 @@ export async function handleChangeStatusInvitation(mutation: any, id: string | u }) if ('data' in response) - status === QueryStatuses.ACCEPTED + status === StatusesEnum.ACCEPTED ? message.success(`Вы успешно приняли заявку`) : message.success(`Вы успешно отклонили заявку`) } diff --git a/apps/schools/domains/common/redux/serializers.ts b/apps/schools/domains/common/redux/serializers.ts index 14ac85d7..6165fb90 100644 --- a/apps/schools/domains/common/redux/serializers.ts +++ b/apps/schools/domains/common/redux/serializers.ts @@ -139,6 +139,16 @@ export interface GetAnalytics { CANCELED: number } +export interface GetTicketAnalytics { + 'ticket-analytics': { + IN_PROGRESS: number + SENT: number + ACCEPTED: number + DECLINED: number + CANCELED: number + } +} + export interface GetQueryStatus { id?: string status: QueriesTypes @@ -189,6 +199,12 @@ export interface GetFamily { name: string } +export interface GetAnalyticsData { + date_from?: string + date_to?: string + organization_id: string +} + export interface GetFamilyRecipient { id?: string name: string diff --git a/apps/schools/domains/organization/redux/interfaces.ts b/apps/schools/domains/organization/redux/interfaces.ts index 84d1d24d..eb95fd90 100644 --- a/apps/schools/domains/organization/redux/interfaces.ts +++ b/apps/schools/domains/organization/redux/interfaces.ts @@ -106,12 +106,6 @@ export interface AllStudentJoinCircleQueriesData extends BasePaginationData { student__student_profile__phone?: string } -export interface GetOrganizationAnalyticsData { - date_from?: string - date_to?: string - organization_id: string -} - export interface GetOrganizationCircleList { id: string name: string diff --git a/apps/schools/domains/organization/redux/organizationApi.ts b/apps/schools/domains/organization/redux/organizationApi.ts index c31bbedb..12dabb15 100644 --- a/apps/schools/domains/organization/redux/organizationApi.ts +++ b/apps/schools/domains/organization/redux/organizationApi.ts @@ -17,12 +17,12 @@ import { GetOrganizationCircleListData, GetCurrentCircleData, AllStudentJoinCircleQueriesData, - GetOrganizationAnalyticsData, } from './interfaces' import { GetEmployee } from '../../employee/redux/interfaces' import { CreateOrganizationInviteEmployee, GetAnalytics, + GetAnalyticsData, GetCircleInviteStudent, GetOrganizationInviteEmployee, GetOrganizationSender, @@ -32,6 +32,7 @@ import { GetTeacher, UpdateOrganizationInviteEmployee, } from '@domains/common/redux/serializers' +import { GetTicket, GetTicketsData } from '@domains/ticket/redux/serializers' const organizationApi = commonApi.injectEndpoints({ endpoints: (build) => ({ @@ -166,7 +167,7 @@ const organizationApi = commonApi.injectEndpoints({ }), providesTags: (result) => providesList(result?.results, 'StudentJoinCircleQuery'), }), - getOrganizationAnalytics: build.query<{ analytics: GetAnalytics }, GetOrganizationAnalyticsData>({ + getOrganizationAnalytics: build.query<{ analytics: GetAnalytics }, GetAnalyticsData>({ query: (params) => ({ url: `/organization-management/organizations/${params.organization_id}/analytics`, method: 'GET', @@ -174,6 +175,20 @@ const organizationApi = commonApi.injectEndpoints({ }), providesTags: ['StudentJoinCircleQuery'], }), + getTicketsAnalytics: build.query<{ 'ticket-analytics': GetAnalytics }, GetAnalyticsData>({ + query: (params) => ({ + url: `/organization-management/organizations/${params.organization_id}/ticket-analytics`, + method: 'GET', + params: params, + }), + }), + getAllTickets: build.query, GetTicketsData>({ + query: (params) => ({ + url: `/organization-management/organizations/${params.organization_id}/family-tickets`, + method: 'GET', + params: params, + }), + }), }), }) @@ -197,4 +212,6 @@ export const { useGetAllCirclesQuery, useGetAllJoinCircleQueriesQuery, useGetOrganizationAnalyticsQuery, + useGetTicketsAnalyticsQuery, + useGetAllTicketsQuery, } = organizationApi diff --git a/apps/schools/domains/query/components/queryList/constants.ts b/apps/schools/domains/query/components/queryList/constants.ts index 3575adf2..234e4358 100644 --- a/apps/schools/domains/query/components/queryList/constants.ts +++ b/apps/schools/domains/query/components/queryList/constants.ts @@ -1,4 +1,4 @@ -import { QueryStatuses } from '@domains/common/constants/Enums' +import { StatusesEnum } from '@domains/common/constants/Enums' import { ACCEPTED_FILTER_COLOR, CANCELED_FILTER_COLOR, @@ -23,9 +23,9 @@ interface TagType { } export const StatusDictionary: { [key: string]: TagType } = { - [QueryStatuses.SENT]: { text: 'Отправлено', color: SENT_FILTER_COLOR, antdColor: 'gold' }, - [QueryStatuses.IN_PROGRESS]: { text: 'На рассмотрении', color: IN_PROGRESS_FILTER_COLOR, antdColor: 'blue' }, - [QueryStatuses.ACCEPTED]: { text: 'Принято', color: ACCEPTED_FILTER_COLOR, antdColor: 'green' }, - [QueryStatuses.CANCELED]: { text: 'Отменено', color: CANCELED_FILTER_COLOR, antdColor: 'volcano' }, - [QueryStatuses.DECLINED]: { text: 'Отклонено', color: DECLINED_FILTER_COLOR, antdColor: 'red' }, + [StatusesEnum.SENT]: { text: 'Отправлено', color: SENT_FILTER_COLOR, antdColor: 'gold' }, + [StatusesEnum.IN_PROGRESS]: { text: 'На рассмотрении', color: IN_PROGRESS_FILTER_COLOR, antdColor: 'blue' }, + [StatusesEnum.ACCEPTED]: { text: 'Принято', color: ACCEPTED_FILTER_COLOR, antdColor: 'green' }, + [StatusesEnum.CANCELED]: { text: 'Отменено', color: CANCELED_FILTER_COLOR, antdColor: 'volcano' }, + [StatusesEnum.DECLINED]: { text: 'Отклонено', color: DECLINED_FILTER_COLOR, antdColor: 'red' }, } diff --git a/apps/schools/domains/student/components/studentList/index.tsx b/apps/schools/domains/student/components/studentList/index.tsx index e491ed46..f72267d6 100644 --- a/apps/schools/domains/student/components/studentList/index.tsx +++ b/apps/schools/domains/student/components/studentList/index.tsx @@ -9,7 +9,7 @@ import { createSearchTextForRequest } from '@domains/common/utils/searchText' import { RowType, TableType } from './interfaces' import { searchInvitesColumns, searchStudentsColumns } from './constants' import { useGetAllStudentInvitationsQuery, useGetAllStudentsQuery } from '@domains/organization/redux/organizationApi' -import { QueryStatuses } from '@domains/common/constants/Enums' +import { StatusesEnum } from '@domains/common/constants/Enums' import EmptyWrapper from '@domains/common/components/containers/EmptyWrapper' import { AppRoutes, RoutePath } from '@domains/common/constants/routerEnums' @@ -19,7 +19,7 @@ export function StudentList() { const { data: invites, isLoading: isLoadingInvites } = useGetAllStudentInvitationsQuery({ circle__organization__id: organizationId, - status: QueryStatuses.SENT, + status: StatusesEnum.SENT, or_search: createSearchTextForRequest(searchRequestText, searchInvitesColumns), }) diff --git a/apps/schools/domains/ticket/components/ticketList/constants.ts b/apps/schools/domains/ticket/components/ticketList/constants.ts new file mode 100644 index 00000000..f775aa7b --- /dev/null +++ b/apps/schools/domains/ticket/components/ticketList/constants.ts @@ -0,0 +1,18 @@ +import { StatusesEnum } from '@domains/common/constants/Enums' +import type { LiteralUnion } from 'antd/lib/_util/type' +import type { PresetColorType, PresetStatusColorType } from 'antd/lib/_util/colors' +import { CANCELED_FILTER_COLOR, IN_PROGRESS_FILTER_COLOR, SENT_FILTER_COLOR } from './styles/styles' + +export const searchTicketsColumns = ['family__name', 'ticket_comment__value'] + +interface TagType { + text: string + color: string + antdColor: LiteralUnion +} + +export const StatusDictionary: { [key: string]: TagType } = { + [StatusesEnum.SENT]: { text: 'Новое', color: SENT_FILTER_COLOR, antdColor: 'red' }, + [StatusesEnum.IN_PROGRESS]: { text: 'Открыто', color: IN_PROGRESS_FILTER_COLOR, antdColor: 'blue' }, + [StatusesEnum.CANCELED]: { text: 'Закрыто', color: CANCELED_FILTER_COLOR, antdColor: 'green' }, +} diff --git a/apps/schools/domains/ticket/components/ticketList/index.tsx b/apps/schools/domains/ticket/components/ticketList/index.tsx new file mode 100644 index 00000000..5a0505dc --- /dev/null +++ b/apps/schools/domains/ticket/components/ticketList/index.tsx @@ -0,0 +1,196 @@ +import React, { useEffect, useState } from 'react' +import { Tag, Typography } from 'antd' +import styles from './styles/styles.module.scss' +import { useOrganization } from '@domains/organization/providers/organizationProvider' +import { Table } from '@domains/common/components/table' +import { createSearchTextForRequest } from '@domains/common/utils/searchText' +import { RowType, TableType } from './interfaces' +import { searchTicketsColumns, StatusDictionary } from './constants' +import { + useGetAllJoinCircleQueriesQuery, + useGetAllTicketsQuery, + useGetOrganizationAnalyticsQuery, + useGetTicketsAnalyticsQuery, +} 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 { isReactElement } from '@domains/common/utils/react' +import { sumObjectValues } from '@domains/common/utils/sumObjectValues' +import { CloseCircleOutlined, SearchOutlined } from '@ant-design/icons' +import { Input } from '@domains/common/components/input' +import { BubbleFilter } from '@domains/common/components/bubbleFilter' +import { BubbleFilterListItem } from '@domains/common/components/bubbleFilter/interface' +import { useQueryState } from 'next-usequerystate' +import { parseAsArrayOf, parseAsString } from 'next-usequerystate' +import { AppRoutes, RoutePath } from '@domains/common/constants/routerEnums' + +export function TicketList() { + const [inputText, setInputText] = useState('') + const [searchRequestText, setSearchRequestText] = useState('') + const [isTableLoading, setIsTableLoading] = useState(false) + const { organizationId } = useOrganization() + + const [statuses, setStatuses] = useQueryState( + 'statuses', + parseAsArrayOf(parseAsString).withOptions({ + history: 'push', + }), + ) + + const { data: analytics, isLoading: isAnalyticsLoading } = useGetTicketsAnalyticsQuery({ + organization_id: organizationId, + }) + + const bubbleFilterItems: any = {} + + for (const key in StatusDictionary) { + const obj = StatusDictionary[key] + + bubbleFilterItems[key] = { + key: key, + text: obj.text, + color: obj.color, + count: analytics ? (analytics['ticket-analytics'] as unknown as { [index: string]: number })[key] : 0, + isSelected: statuses?.includes(key) ?? false, + onClick: () => { + setStatuses((x) => [...(x ?? []), key]) + }, + onExit: () => { + setStatuses((x) => { + const res = [...(x ?? []).filter((y) => y != key)] + return res.length === 0 ? null : res + }) + }, + } as BubbleFilterListItem + } + + const { data: tickets, isLoading: isTicketsLoading } = useGetAllTicketsQuery({ + organization_id: organizationId, + or_search: createSearchTextForRequest(searchRequestText, searchTicketsColumns), + }) + + console.log(tickets) + + const reformattedData = mapReturnedData(tickets, (query) => { + const transformedQuery = structuredClone(query) as unknown as TableType + transformedQuery.last_message = query.last_comment.value + transformedQuery.sender = query.last_comment?.sender?.name || query.sender?.name + return transformedQuery + }) + + useEffect(() => { + if (!isTicketsLoading && tickets) { + setIsTableLoading(false) + } + }, [tickets]) + + return ( + +
+ Обращения +
+ { + setIsTableLoading(true) + setInputText(text.target.value) + setTimeout(() => { + setSearchRequestText(text.target.value) + }, 1000) + }} + customType={'inputSearch'} + placeholder={'Поиск'} + value={inputText} + children={ + <> + + {inputText && ( + { + setInputText('') + setSearchRequestText('') + }} + /> + )} + + } + /> + + + loading={isTableLoading} + customType={'tableWithoutSearch'} + columnsTitlesAndKeys={[ + ['Создано', 'created_at'], + ['Статус', 'status'], + ['Содержание', 'last_message'], + ['Отправитель', 'sender'], + ]} + customWidths={[10, 10, 40, 30]} + data={reformattedData} + isLoading={isTicketsLoading} + mainRoute={RoutePath[AppRoutes.TICKETS_LIST]} + searchFields={['created_at', 'last_message', 'sender']} + customFields={{ + created_at: ({ text, searchText }) => { + const [date, time] = new Intl.DateTimeFormat('pt-BR', { + dateStyle: 'short', + timeStyle: 'short', + }) + .format(new Date(text)) + .replaceAll('/', '.') + .split(',') + + return ( +
+
+ +
+ +
+ +
+
+ ) + }, + status: ({ text }) => { + return ( + + {StatusDictionary[text].text} + + ) + }, + }} + customFilterFields={{ + status: { + filters: Object.entries(StatusDictionary).map(([key, value]) => ({ + value: key, + text: value.text, + })), + filteredValue: statuses ?? [], + onFilter: (value, record) => { + const obj = (record as any)['status'] + if (!isReactElement(obj)) return obj === value + + return obj.key === value + }, + }, + }} + sortFields={['created_at']} + searchRequestText={searchRequestText} + setSearchRequestText={setSearchRequestText} + onChange={(pagination, filters, sorter) => { + const localStatuses = [...(filters['status'] ?? [])] as string[] + setStatuses(localStatuses.length === 0 ? null : localStatuses) + }} + /> +
+ ) +} diff --git a/apps/schools/domains/ticket/components/ticketList/interfaces.ts b/apps/schools/domains/ticket/components/ticketList/interfaces.ts new file mode 100644 index 00000000..35f15789 --- /dev/null +++ b/apps/schools/domains/ticket/components/ticketList/interfaces.ts @@ -0,0 +1,15 @@ +export interface RowType { + id?: string + created_up?: string + status?: string + last_message?: string + sender?: string +} + +export interface TableType { + id?: string + created_up?: string + status?: string + last_message?: string + sender?: string +} diff --git a/apps/schools/domains/ticket/components/ticketList/styles/styles.module.scss b/apps/schools/domains/ticket/components/ticketList/styles/styles.module.scss new file mode 100644 index 00000000..e1852186 --- /dev/null +++ b/apps/schools/domains/ticket/components/ticketList/styles/styles.module.scss @@ -0,0 +1,60 @@ +@import '../../../../common/components/styles/abstracts/common'; + +.tableContainer { + @extend %table; +} + +.inputSearch { + margin-bottom: 0; +} + +.allQueriesText { + font-family: "Open Sans", sans-serif; + font-size: 16px; + font-style: normal; + font-weight: 600; + line-height: 140%; +} + +.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; + } +} + +.tags { + border-radius: 8px; +} \ No newline at end of file diff --git a/apps/schools/domains/ticket/components/ticketList/styles/styles.ts b/apps/schools/domains/ticket/components/ticketList/styles/styles.ts new file mode 100644 index 00000000..0a7bffeb --- /dev/null +++ b/apps/schools/domains/ticket/components/ticketList/styles/styles.ts @@ -0,0 +1,3 @@ +export const IN_PROGRESS_FILTER_COLOR = '#2F54EB' +export const SENT_FILTER_COLOR = '#EB3468' +export const CANCELED_FILTER_COLOR = '#52C41A' diff --git a/apps/schools/domains/ticket/redux/serializers.ts b/apps/schools/domains/ticket/redux/serializers.ts new file mode 100644 index 00000000..7e00603e --- /dev/null +++ b/apps/schools/domains/ticket/redux/serializers.ts @@ -0,0 +1,42 @@ +import { GetFamily, GetOrganization } from '@domains/common/redux/serializers' +import { BasePaginationData, QueriesTypes } from '@domains/common/redux/interfaces' + +export interface GetTicket { + id?: string + last_comment: GetTicketComment + recipient: GetOrganization + created_at?: string + unread_sender_comments_count?: string + unread_recipient_comments_count?: string + sender?: GetFamily + status?: QueriesTypes +} + +export interface GetTicketComment { + id?: string + is_sender: boolean + is_seen?: boolean + value: string + created_at?: string + sender: GetTicketCommentSender +} + +export interface GetTicketCommentSender { + id: string + name: string +} + +export interface GetTicketsData extends BasePaginationData { + id?: string + created_at?: string + recipient_id?: string + recipient_ct?: string + status?: string + or_search?: string + family__id?: string + family__name?: string + family__parent_phone?: string + ticket_comment__id?: string + ticket_comment__value?: string + organization_id?: string +} diff --git a/apps/schools/pages/ticket/index.tsx b/apps/schools/pages/ticket/index.tsx new file mode 100644 index 00000000..c09a41d0 --- /dev/null +++ b/apps/schools/pages/ticket/index.tsx @@ -0,0 +1,23 @@ +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 { TicketList } from '@domains/ticket/components/ticketList' + +const TicketsPageContent = () => { + return ( + <> + + Обращения + + + + + + + + ) +} + +export default TicketsPageContent