Files
G4F/StaticHelper/source/docs.md

7.6 KiB
Raw Blame History

Требования к коду

Используется библиотека react-router-dom и react=markdown.

Все компоненты должны быть функциональными. props должны быть сразу распакованы. export без default

Пример:

export function ProfessionPage() {
    const {professionId} = useParams<{ professionId: string }>();
}

Используйте современные практики React (например, хуки). При создании новых компонентов добавьте комментарии.

Если для задачи необходимы новые типы, интерфейсы или вспомогательные компоненты - создавай их в соответвующих файлах.

Документария

Существующие типы

types/api.ts

export interface ApiResponse {
    body?: object,
    success: boolean
}
export interface PageResponse<T>{
    count: number;
    next?: string;
    previous?: string;
    results: T[]
}

types/common.ts

export interface UniqueItem{
    id: number;
}

export interface PageControl<T>{
    items: T[] | null;
    hasNext: boolean;
    hasPrevious: boolean;
    nextPage(): void;
    previousPage(): void;
}
export interface FieldInfo {
    name: string;
    type: string;
    title: string;
    format?: string;
}

types/survey.ts

import {UniqueItem} from "./common.ts";

export interface Survey extends UniqueItem{
    title: string;
    description: string;
}
interface Statement extends UniqueItem{
    text: string;
    score_variable: number;
}
export enum QuestionType{
    QuestionPair,
    AgreementQuestion
}
export interface Question extends UniqueItem{
    questionType: QuestionType
}
export interface QuestionPair extends Question{
    statements: Statement[]
}
export interface AgreementQuestion extends Question{
    question: string;
    score_variable: number;
}
export interface ScoreVariable {
    id: string;
    name: string;
    title: string;
    description: string;
    survey: number;
}
export interface Profession extends UniqueItem {
    name: string;
    description: string;
}
export interface Specialty extends UniqueItem {
    name: string;
    institution: number;
    link?: string;
}
export interface Institution extends UniqueItem {
    name: string;
}

types/users.ts

import {UniqueItem} from "./common.ts";

export type UserContextType = {
    user: Account | undefined;
    login: (credentials: TokenObtainPair) => Promise<void>;
    logout: () => void;
};
export interface ContactData{
    first_name: string;
    last_name?: string;
    middle_name?: string;
    phone?: string;
    email?:string;
}
export interface Account extends UniqueItem, ContactData{
    login: string;
    role?: number;
    roleTitle?: string;
    is_staff: boolean;
    is_active: boolean;
}
export interface TokenObtainPair {
    login: string;
    password: string;
}
export interface TokenRefresh {
    refresh: string;
}
export interface TokenVerify {
    token: string;
}
export interface JwtTokenResponse {
    access: string;
    refresh: string;
}

Способы запросов

Вместо fetch запросы должны проходить при помощи специальных функций/функции

API/common.ts

async function getFetch(path: string) // Get method
async function postFetch(
    path: string,
    body: object | FormData
) // Post method
async function patchFetch(
    path: string,
    body: object | FormData
) // Patch method
async function deleteFetch(path: string) // Delete method

Хуки

Для загрузки данных

Для упрощения работы с api созданы следующие хуки

API/hooks.ts

function useDataPage<T>(application:string, endpoint: string, params:{[key:string]:string|number}={}, needLoad:boolean=true):PageControl<T> 
function useData<T>(application:string, endpoint: string, id: string|number, needLoad:boolean=true): T|null|undefined
function useCachedData<T>(application: string, endpoint: string): (id: string | number, needLoad: boolean = true)=> T|undefined|null 
  • application - Название модуля

  • endpoint - Название объекта над которым идёт работа

  • id - id искомого объекта

  • params - дополнительные параметры (например фильтрация)

  • needLoad - указывает нужно ли загружать список/объект прямо сейчас

  • null - загрузка еще не происходила

  • undefined - не найдено

  • T (объект)

Для ленивой загрузки элементов

components/LoadingData.tsx

function LoadingData({data, children}: {data: object|null|undefined, children: (ReactElement | null | undefined | boolean)[]})

Для загрузки отдельного элемента. Если data

  • null - Возвращает <div className={"loading"}>Идёт загрузка...
  • undefined - <Link className={"not-found"} to={"/"}>404 НЕ НАЙДЕНО
  • иначе возвращает children

components/LoadingList.tsx

function LoadingList({data, listElement}: {data: UniqueItem[]|null, listElement(e:UniqueItem, i:number):unknown})

Для загрузки списка. Если data не null - то возвращает элементы результаты listElement

Примеры

export function ProfessionPage() {
    const { professionId } = useParams<{ professionId: string }>();
    const profession = useData<Profession>('surveys', 'professions', professionId || 0);
    const specialties = useDataPage<Specialty>('surveys', 'specialties', { profession: professionId || 0 }, !!profession);

    const institutions = useCachedData<Institution>("surveys", "institutions");

    return (
        <div>
            <LoadingData data={profession}>
                <h1>{profession?.name}</h1>
                <div className="description">
                    <ReactMarkdown>{profession?.description || ''}</ReactMarkdown>
                </div>
                <div className="specialties-block">
                    {specialties.items != null ? <h2>Где можно обучиться</h2>:null}
                    <LoadingList
                        data={specialties.items}
                        listElement={specialty => (
                            <SpecialtyBlock
                                key={specialty.id}
                                specialty={specialty as Specialty}
                                institution={institutions((specialty as Specialty).institution)}
                            />
                        )}
                    />
                </div>
            </LoadingData>
        </div>
    );
}

Автодокументация

api/hooks.ts

/**
 * Хук для получения документации swagger JSON и извлечения структур.
 * @param applicationName Название модуля/приложения.
 * @param endpointName Название эндпоинта.
 * @returns Массив структур без ID с полями: название, тип, title, format.
 */
export function useApiDocumentation(
    applicationName: string,
    endpointName: string
): { schema: FieldInfo[] | null; loading: boolean; error: Error | null } 

Авторизация

Везде доступен хук useUser():UserContextType | undefined