Skip to content
Open
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
8 changes: 8 additions & 0 deletions public/locales/en/analytics.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,13 @@
"keywords": "Keywords",
"count": "Count"
}
},
"top.users": {
"title": {
"widget": "Top 3 users by speciality"
},
"no.data": {
"widget": "No top users found for this speciality"
}
}
}
6 changes: 0 additions & 6 deletions public/locales/en/collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,6 @@
"aria.label": "Warning: You cannot create a new interview because there is already an active one."
},
"keywords": "Keywords:",
"keyword": {
"label": "Keyword",
"placeholder": "Select keyword",
"not.found": "Keyword not found",
"not.exist": "Keywords are not exist"
},
"tags": {
"title": "Tags"
},
Expand Down
7 changes: 6 additions & 1 deletion public/locales/en/companies.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
"select": {
"choose": "Choose company name",
"empty": "No companies available",
"selected": "Selected company"
"selected": "Selected company",
"filter": {
"title": "Company",
"choose": "Select a company",
"not.found": "Company is not found"
}
}
}
26 changes: 20 additions & 6 deletions public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@
"topics": "Topics"
}
},
"keyword": {
"label": "Keyword",
"placeholder": "Select keyword",
"not.found": "Keyword not found",
"not.exist": "Keywords are not exist"
},
"stub": {
"filter": {
"title": "Unfortunately, nothing was found for the query.",
Expand Down Expand Up @@ -305,12 +311,20 @@
"create": {
"success": "Topic successfully created",
"failed": "Topic could not be created"
}
},
"topics": {
"create": {
"success": "Topic successfully created",
"failed": "Topic could not be created"
},
"edit": {
"success": "Topic successfully changed",
"failed": "Topic could not be changed"
},
"delete": {
"single": {
"success": "Topic successfully deleted",
"failed": "Topic could not be deleted"
},
"multiple": {
"success": "Successfully deleted topics:",
"failed": "Topic could not be deleted:"
}
}
},
"collections": {
Expand Down
8 changes: 8 additions & 0 deletions public/locales/ru/analytics.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,13 @@
"keywords": "Слова",
"count": "Количество"
}
},
"top.users": {
"title": {
"widget": "Топ 3 участника по специальности"
},
"no.data": {
"widget": "В топе по этой специальности пока никого нет"
}
}
}
6 changes: 0 additions & 6 deletions public/locales/ru/collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,6 @@
"title": "Ключевые слова",
"label": "Добавьте ключевые слова в текст"
},
"keyword": {
"label": "Ключевое слово",
"placeholder": "Выберите ключевое слово",
"not.found": "Ключевое слово не найдено",
"not.exist": "Ключевых слов нет"
},
"tags": {
"title": "Теги"
},
Expand Down
7 changes: 6 additions & 1 deletion public/locales/ru/companies.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
"select": {
"choose": "Выберите название компании",
"empty": "Нет доступных компаний",
"selected": "Выбранная компания"
"selected": "Выбранная компания",
"filter": {
"title": "Компания",
"choose": "Выберите компанию",
"not.found": "Компания не найдена"
}
}
}
29 changes: 23 additions & 6 deletions public/locales/ru/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@
"topics": "Темы"
}
},
"keyword": {
"label": "Ключевое слово",
"placeholder": "Выберите ключевое слово",
"not.found": "Ключевое слово не найдено",
"not.exist": "Ключевых слов нет"
},
"stub": {
"filter": {
"title": "К сожалению, по запросу ничего не найдено.",
Expand Down Expand Up @@ -309,12 +315,20 @@
"create": {
"success": "Тема успешно создана",
"failed": "Не удалось создать тему"
}
},
"topics": {
"create": {
"success": "Тема успешно создана",
"failed": "Не удалось создать тему"
},
"edit": {
"success": "Тема успешно изменена",
"failed": "Не удалось изменить тему"
},
"delete": {
"single": {
"success": "Тема успешно удалена",
"failed": "Тему не удалось удалить"
},
"multiple": {
"success": "Успешно удалено тем:",
"failed": "Не удалось удалить тему:"
}
}
},
"collections": {
Expand Down Expand Up @@ -483,6 +497,9 @@
"create": {
"success": "Компания успешно создана",
"failed": "Не удалось создать компанию"
},
"filter": {
"not.found": "Компания не найдена"
}
},
"subscriptions": {
Expand Down
15 changes: 15 additions & 0 deletions src/app/layouts/MainLayout/SkeletonGenerator/SkeletonGenerator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import { SkillsPageSkeleton } from '@/pages/admin/skill/skills';
import { SpecializationsPageSkeleton } from '@/pages/admin/specialization/specializations';
import { UsersTablePageSkeleton } from '@/pages/admin/user/users';
import { AnalyticsPageSkeleton } from '@/pages/analytics/analytics';
import { DifficultQuestionsPageSkeleton } from '@/pages/analytics/difficultQuestions';
import { PopularQuestionsPageSkeleton } from '@/pages/analytics/popularQuestions';
import { PopularSkillsPageSkeleton } from '@/pages/analytics/popularSkills';
import { ProgressSpecializationsPageSkeleton } from '@/pages/analytics/progressSpecializations';
import { SkillsProficiencyPageSkeleton } from '@/pages/analytics/skillsProficiency';
import { CreateQuizPageSkeleton } from '@/pages/interview/createQuiz';
import { InterviewPageSkeleton } from '@/pages/interview/interview';
import { InterviewHistoryPageSkeleton } from '@/pages/interview/interviewHistory';
Expand Down Expand Up @@ -74,6 +79,16 @@ const SkeletonGenerator = () => {
return <CompaniesTablePageSkeleton />;
case ROUTES.media.page:
return <MediaPageSkeleton />;
case ROUTES.analytics.progressSpecializations.route:
return <ProgressSpecializationsPageSkeleton />;
case ROUTES.analytics['skills-proficiency'].route:
return <SkillsProficiencyPageSkeleton />;
case ROUTES.analytics['popular-skills'].route:
return <PopularSkillsPageSkeleton />;
case ROUTES.analytics['popular-questions'].route:
return <PopularQuestionsPageSkeleton />;
case ROUTES.analytics['difficult-questions'].route:
return <DifficultQuestionsPageSkeleton />;
case ROUTES.analytics.page:
return <AnalyticsPageSkeleton />;
default:
Expand Down
2 changes: 2 additions & 0 deletions src/app/msw/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { resourceHandlers } from '@/entities/resource';
import { skillHandlers } from '@/entities/skill';
import { specializationHandlers } from '@/entities/specialization';
import { specializationsProgressHandlers } from '@/entities/specialization';
import { usersRatingHandlers } from '@/entities/user';

import { questionCreateHandlers } from '@/features/question/createQuestion';
import { questionDeleteHandlers } from '@/features/question/deleteQuestion';
Expand Down Expand Up @@ -48,5 +49,6 @@ export const handlers = [
...difficultQuestionsHandler,
...learnedQuestionHandlers,
...specializationsProgressHandlers,
...usersRatingHandlers,
...resourceHandlers,
];
1 change: 0 additions & 1 deletion src/entities/collection/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export { CollectionForm } from './ui/CollectionForm/CollectionForm';
export * from './api/collectionApi';

export { ChooseCollectionAccess } from './ui/ChooseCollectionAccess/ChooseCollectionAccess';
export { KeywordSelect } from './ui/KeywordSelect/KeywordSelect';
export { CollectionPreview } from './ui/CollectionPreview/CollectionPreview';
export { PreviewCollectionsItemSkeleton } from './ui/PreviewCollectionItem/PreviewCollectionsItem.skeleton';
export { CollectionsPreviewSkeleton } from './ui/CollectionPreview/CollectionPreview.sekeleton';
Expand Down
1 change: 1 addition & 0 deletions src/entities/collection/model/types/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export interface GetCollectionsListParamsRequest {
limit?: number;
isFree?: boolean;
specializations?: number | number[];
companies?: string | string[];
keywords?: string[];
titleOrDescriptionSearch?: string;
authorId?: string;
Expand Down
1 change: 1 addition & 0 deletions src/entities/collection/model/types/filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export interface CollectionsFilterParams {
specialization?: number;
isFree?: boolean;
page?: number;
company?: string;
authorId?: string;
isMy?: boolean;
keyword?: string;
Expand Down
10 changes: 9 additions & 1 deletion src/entities/company/api/companyApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,15 @@ const companyApi = baseApi.injectEndpoints({
}),
providesTags: [ApiTags.COMPANIES],
}),
getPublicCompaniesList: build.query<GetCompaniesListResponse, GetCompaniesListParamsRequest>({
query: (params) => ({
url: companyApiUrls.getPublicCompaniesList,
params,
}),
providesTags: [ApiTags.PUBLIC_COMPANIES],
}),
}),
});

export const { useGetCompanyByIdQuery, useGetCompaniesListQuery } = companyApi;
export const { useGetCompanyByIdQuery, useGetCompaniesListQuery, useGetPublicCompaniesListQuery } =
companyApi;
7 changes: 6 additions & 1 deletion src/entities/company/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
export { CompanyCard } from './ui/CompanyCard/CompanyCard';
export { CompanySelect } from './ui/CompanySelect/CompanySelect';
export { useGetCompanyByIdQuery, useGetCompaniesListQuery } from './api/companyApi';
export { PublicCompanySelect } from './ui/PublicCompanySelect/PublicCompanySelect';
export {
useGetCompanyByIdQuery,
useGetCompaniesListQuery,
useGetPublicCompaniesListQuery,
} from './api/companyApi';
export type { Company, CreateOrEditCompanyFormValues } from './model/types/companyTypes';
export { CompanyForm } from './ui/CompanyForm/CompanyForm';

Expand Down
1 change: 1 addition & 0 deletions src/entities/company/model/constants/companyConstants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const companyApiUrls = {
getCompanyById: 'company/:companyId',
getCompaniesList: 'company',
getPublicCompaniesList: 'company/public-companies',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';

import { i18Namespace, Companies } from '@/shared/config';
import { useDebounce } from '@/shared/libs';
import { Dropdown, Option } from '@/shared/ui/Dropdown';
import { Flex } from '@/shared/ui/Flex';
import { Text } from '@/shared/ui/Text';

import { useGetPublicCompaniesListQuery } from '../../api/companyApi';

export type PublicCompanySelectProps = Omit<
React.ComponentProps<typeof Dropdown>,
'options' | 'type' | 'value' | 'onChange' | 'children'
> & {
value?: string;
onChange?: (company?: string) => void;
disabled?: boolean;
};

export const PublicCompanySelect = ({ value, onChange, disabled }: PublicCompanySelectProps) => {
const { t } = useTranslation([i18Namespace.companies]);

const [searchValue, setSearchValue] = useState('');
const [debouncedValue, setDebouncedValue] = useState('');

const debouncedSetValue = useDebounce((value: string) => {
setDebouncedValue(value);
}, 500);

const { data, isFetching } = useGetPublicCompaniesListQuery({
titleOrLegalNameOrDescriptionSearch: debouncedValue,
page: 1,
limit: 10,
});

const companies = data?.data.filter((company) => company.title) || [];

const handleChange = (newValue?: string) => {
if (disabled) return;
onChange?.(newValue);
};

const emptyCompany = {
value: '',
label: t(Companies.SELECT_FILTER_CHOOSE),
};

const handleSearchChange = (val: string) => {
setSearchValue(val);
debouncedSetValue(val);
};

const options = useMemo(() => {
return companies.map((company) => ({
value: company.id.toString(),
label: company.title as string,
}));
}, [companies]);
const selectCompany = options.find((option) => option.value === value) || emptyCompany;
const notFoundText = t(Companies.SELECT_FILTER_NOT_FOUND);
const displayValue = options.length === 0 ? notFoundText : searchValue || selectCompany.label;

return (
<Flex direction="column" align="start" gap="8">
<Text variant="body2" color="black-700">
{t(Companies.SELECT_FILTER_TITLE)}
</Text>
<Dropdown
size="S"
label={selectCompany.label}
disabled={disabled}
value={displayValue}
isInput={true}
inputValue={searchValue}
onChangeValue={handleSearchChange}
onSelect={(val) => {
const selected = options.find((opt) => opt.value === val);
handleChange(!val ? undefined : String(val));
!selected?.label ? handleSearchChange('') : '';
setSearchValue(selected?.label ?? '');
}}
>
{options.length === 0 ? (
<Option value="not-found" label={notFoundText} disabled />
) : (
options.map((option) => (
<Option
value={option.value}
label={option.label}
key={option.value}
disabled={isFetching}
/>
))
)}
</Dropdown>
</Flex>
);
};
15 changes: 0 additions & 15 deletions src/entities/guru/model/constants/gurus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,21 +124,6 @@ export const gurus: Guru[] = [
landing: 'https://notsystemanalysis.ru/',
},
},
{
title: '1C Developer Guru',
name: 'Nadvorny Vladimir',
specializations: [41, 43],
hasPractice: false,
description:
'Отвечает за направление 1C: следит за актуальностью материалов, помогает формировать контент и добавляет вопросы для практики и интервью.',
image:
'https://e5e684b1-4a6a-4be5-b7ee-b2b678239d61.selstorage.ru/gurus/%D0%B3%D1%83%D1%80%D1%831%D1%81.jpg',
socials: {
telegram: 'https://t.me/Mentor1CProfi',
profileId: '73771794-59d6-4c5b-8449-07e1887ea0d2',
landing: 'https://t.me/Mentor1CProfi',
},
},
{
title: 'Unity Guru',
name: 'Oleg Miroshkin',
Expand Down
Loading