diff --git a/src/app/services/api.ts b/src/app/services/api.ts index b64978f..a326069 100644 --- a/src/app/services/api.ts +++ b/src/app/services/api.ts @@ -15,6 +15,6 @@ const baseQuery = fetchBaseQuery({ export const api = createApi({ baseQuery: retry(baseQuery, { maxRetries: 2 }), - tagTypes: ["User", "Status", "Submission"], + tagTypes: ["User", "Status", "Submission", "ProblemInfo", "TaskInfo"], endpoints: () => ({}), }); diff --git a/src/app/services/problem.ts b/src/app/services/problem.ts new file mode 100644 index 0000000..0a6d6d7 --- /dev/null +++ b/src/app/services/problem.ts @@ -0,0 +1,96 @@ +import type { Meta, WithCount, Wrap } from "./base"; +import type { UserProfile } from "./user"; +import { api } from "./api"; + +export interface RuntimeInfo { + MemoryLimit: number; + NProcLimit: number; + TimeLimit: number; +} + +export interface TaskInfo { + Languages: { + Lang: string; + Runtime: { + Compile: RuntimeInfo; + Run: RuntimeInfo; + }; + }[]; + Tasks: { Id: number; Points: number }[]; +} + +export interface ProblemInfo { + meta: Meta; + title: string; + statement: string; + tags: { Elements: string[] }; + provider: UserProfile; + is_enabled: boolean; +} + +export interface CreateVersionRequest { + pid: number; + storage_key: string; +} + +export interface DetailRequest { + pid: number; +} + +export interface DetailResponse { + context: TaskInfo; + problem: ProblemInfo; +} + +export interface SearchRequest { + keyword: string; + tag: string; + offset?: number; + limit: number; +} + +export type SearchResponse = WithCount; + +export interface UpdateRequest { + pid: number; + title: string; + statement: string; + tags: string[]; + is_enabled: boolean; +} + +export interface UploadResponse { + key: string; + url: string; +} + +export const problemApi = api.injectEndpoints({ + endpoints: (builder) => ({ + search: builder.query, SearchRequest>({ + query: (data: SearchRequest) => ({ + url: "/problem/search", + method: "POST", + body: data, + }), + providesTags: (result) => + result && result.body.count > 0 + ? [ + ...result.body.data.map((p: ProblemInfo) => ({ + type: "ProblemInfo" as const, + id: p.meta.ID, + })), + { type: "ProblemInfo", id: "Search" }, + ] + : [{ type: "ProblemInfo", id: "Search" }], + }), + detail: builder.query, DetailRequest>({ + query: (data: DetailRequest) => ({ + url: "/problem/search", + method: "POST", + body: data, + }), + providesTags: (result) => (result ? [{ type: "TaskInfo", id: result.body.problem.meta.ID }] : []), + }), + // TODO: admin endpoints: version, update, upload + }), +});