mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-08 17:08:18 +00:00
108 lines
3.1 KiB
TypeScript
108 lines
3.1 KiB
TypeScript
import type {
|
|
PortalMediaKind,
|
|
SupportDocPayload,
|
|
SupportDocSlug,
|
|
SupportDocumentDetail,
|
|
SupportDocVersionDetail,
|
|
SupportDocVersionSummary,
|
|
} from "@edr/types";
|
|
|
|
import { api as client } from "../auth/http";
|
|
|
|
const ROOT = "/support-content";
|
|
const BASE = `${ROOT}/documents`;
|
|
|
|
/**
|
|
* Customer-facing help/FAQ/legal copy for the freight portal. The client's
|
|
* response interceptor already unwraps the `{ success, data }` envelope, so
|
|
* every method is a one-liner.
|
|
*/
|
|
export const portalContentService = {
|
|
async getBySlug(slug: SupportDocSlug): Promise<SupportDocumentDetail> {
|
|
const { data } = await client.get<SupportDocumentDetail>(`${BASE}/${slug}`);
|
|
return data;
|
|
},
|
|
|
|
/**
|
|
* Replaces the document's whole payload. Whole-payload rather than per-field
|
|
* on purpose: one Save becomes exactly one version, which is what keeps the
|
|
* history list readable.
|
|
*/
|
|
async update(
|
|
slug: SupportDocSlug,
|
|
payload: SupportDocPayload,
|
|
note?: string,
|
|
): Promise<SupportDocumentDetail> {
|
|
const { data } = await client.patch<SupportDocumentDetail>(
|
|
`${BASE}/${slug}`,
|
|
{ payload, note },
|
|
);
|
|
return data;
|
|
},
|
|
|
|
async listVersions(slug: SupportDocSlug): Promise<SupportDocVersionSummary[]> {
|
|
const { data } = await client.get<SupportDocVersionSummary[]>(
|
|
`${BASE}/${slug}/versions`,
|
|
);
|
|
return data;
|
|
},
|
|
|
|
async getVersion(
|
|
slug: SupportDocSlug,
|
|
version: number,
|
|
): Promise<SupportDocVersionDetail> {
|
|
const { data } = await client.get<SupportDocVersionDetail>(
|
|
`${BASE}/${slug}/versions/${version}`,
|
|
);
|
|
return data;
|
|
},
|
|
|
|
/**
|
|
* Uploads an image or video and returns its object *key*. The key is what
|
|
* gets saved in the document; `url` is only for showing the editor a preview
|
|
* right now, and expires.
|
|
*/
|
|
async uploadMedia(
|
|
file: File,
|
|
onProgress?: (percent: number | null) => void,
|
|
): Promise<{ key: string; kind: PortalMediaKind; url: string }> {
|
|
const form = new FormData();
|
|
form.append("file", file);
|
|
|
|
const { data } = await client.post<{
|
|
key: string;
|
|
kind: PortalMediaKind;
|
|
url: string;
|
|
}>(`${ROOT}/media`, form, {
|
|
// A video is big enough that a stalled connection would otherwise sit on
|
|
// a spinner forever with nothing to tell the author it had failed.
|
|
timeout: 2 * 60 * 1000,
|
|
onUploadProgress: (event) =>
|
|
onProgress?.(
|
|
event.total ? Math.round((event.loaded / event.total) * 100) : null,
|
|
),
|
|
});
|
|
return data;
|
|
},
|
|
|
|
/** Resolves one stored key to a temporary URL, for editor previews. */
|
|
async mediaUrl(key: string): Promise<string> {
|
|
const { data } = await client.get<{ url: string }>(`${ROOT}/media-url`, {
|
|
params: { key },
|
|
});
|
|
return data.url;
|
|
},
|
|
|
|
/** Re-saves an old payload as a new version — never destructive. */
|
|
async restore(
|
|
slug: SupportDocSlug,
|
|
version: number,
|
|
): Promise<SupportDocumentDetail> {
|
|
const { data } = await client.post<SupportDocumentDetail>(
|
|
`${BASE}/${slug}/versions/${version}/restore`,
|
|
{},
|
|
);
|
|
return data;
|
|
},
|
|
};
|