Add Go/Postgres admin APIs, Angular admin UI, manual build flow, asset uploads, markdown import/export, configurable slug generation, and the Yar reading theme. Exclude local docs and generated development artifacts from version control.
117 lines
2.8 KiB
TypeScript
117 lines
2.8 KiB
TypeScript
import { HttpClient, HttpParams } from '@angular/common/http';
|
|
import { Injectable, inject } from '@angular/core';
|
|
|
|
import {
|
|
AssetResponse,
|
|
BuildJobResponse,
|
|
LoginResponse,
|
|
DeletePostResponse,
|
|
PostInput,
|
|
PostResponse,
|
|
PostStatus,
|
|
PostsResponse,
|
|
SlugResponse
|
|
} from './models';
|
|
|
|
@Injectable({ providedIn: 'root' })
|
|
export class AdminApiService {
|
|
private readonly http = inject(HttpClient);
|
|
private readonly baseUrl = '/api/admin';
|
|
|
|
me() {
|
|
return this.http.get<{ user: LoginResponse['user'] }>(`${this.baseUrl}/me`, {
|
|
withCredentials: true
|
|
});
|
|
}
|
|
|
|
login(username: string, password: string) {
|
|
return this.http.post<LoginResponse>(
|
|
`${this.baseUrl}/login`,
|
|
{ username, password },
|
|
{ withCredentials: true }
|
|
);
|
|
}
|
|
|
|
logout() {
|
|
return this.http.post<{ ok: boolean }>(`${this.baseUrl}/logout`, {}, { withCredentials: true });
|
|
}
|
|
|
|
listPosts(status: PostStatus | '', limit?: number, offset?: number) {
|
|
let params = new HttpParams();
|
|
if (status) {
|
|
params = params.set('status', status);
|
|
}
|
|
if (limit) {
|
|
params = params.set('limit', String(limit));
|
|
}
|
|
if (offset) {
|
|
params = params.set('offset', String(offset));
|
|
}
|
|
return this.http.get<PostsResponse>(`${this.baseUrl}/posts`, {
|
|
params,
|
|
withCredentials: true
|
|
});
|
|
}
|
|
|
|
getPost(id: string) {
|
|
return this.http.get<PostResponse>(`${this.baseUrl}/posts/${id}`, {
|
|
withCredentials: true
|
|
});
|
|
}
|
|
|
|
createPost(input: PostInput) {
|
|
return this.http.post<PostResponse>(`${this.baseUrl}/posts`, input, {
|
|
withCredentials: true
|
|
});
|
|
}
|
|
|
|
updatePost(id: string, input: PostInput) {
|
|
return this.http.put<PostResponse>(`${this.baseUrl}/posts/${id}`, input, {
|
|
withCredentials: true
|
|
});
|
|
}
|
|
|
|
deletePost(id: string) {
|
|
return this.http.delete<DeletePostResponse>(`${this.baseUrl}/posts/${id}`, {
|
|
withCredentials: true
|
|
});
|
|
}
|
|
|
|
publishPost(id: string) {
|
|
return this.http.post<PostResponse & BuildJobResponse>(
|
|
`${this.baseUrl}/posts/${id}/publish`,
|
|
{},
|
|
{ withCredentials: true }
|
|
);
|
|
}
|
|
|
|
buildPost(id: string) {
|
|
return this.http.post<BuildJobResponse>(
|
|
`${this.baseUrl}/posts/${id}/build`,
|
|
{},
|
|
{ withCredentials: true }
|
|
);
|
|
}
|
|
|
|
getBuildJob(id: string) {
|
|
return this.http.get<BuildJobResponse>(`${this.baseUrl}/build-jobs/${id}`, {
|
|
withCredentials: true
|
|
});
|
|
}
|
|
|
|
uploadAsset(file: File) {
|
|
const body = new FormData();
|
|
body.append('file', file);
|
|
return this.http.post<AssetResponse>(`${this.baseUrl}/assets`, body, {
|
|
withCredentials: true
|
|
});
|
|
}
|
|
|
|
generateSlug(title: string, summary: string, postId?: string) {
|
|
return this.http.post<SlugResponse>(
|
|
`${this.baseUrl}/slug`,
|
|
{ title, summary, postId },
|
|
{ withCredentials: true }
|
|
);
|
|
}
|
|
}
|