feat: add user profile views and library management
Some checks failed
CI / UI / Build (push) Failing after 11s
CI / Scraper / Lint (pull_request) Failing after 15s
CI / UI / Docker Push (push) Has been skipped
CI / Scraper / Test (pull_request) Successful in 20s
CI / Scraper / Docker Push (pull_request) Has been skipped
CI / UI / Build (pull_request) Failing after 17s
CI / UI / Docker Push (pull_request) Has been skipped
iOS CI / Build (push) Successful in 3m40s
iOS CI / Build (pull_request) Successful in 1m49s
iOS CI / Test (push) Successful in 4m24s
iOS CI / Test (pull_request) Successful in 4m46s
Some checks failed
CI / UI / Build (push) Failing after 11s
CI / Scraper / Lint (pull_request) Failing after 15s
CI / UI / Docker Push (push) Has been skipped
CI / Scraper / Test (pull_request) Successful in 20s
CI / Scraper / Docker Push (pull_request) Has been skipped
CI / UI / Build (pull_request) Failing after 17s
CI / UI / Docker Push (pull_request) Has been skipped
iOS CI / Build (push) Successful in 3m40s
iOS CI / Build (pull_request) Successful in 1m49s
iOS CI / Test (push) Successful in 4m24s
iOS CI / Test (pull_request) Successful in 4m46s
- Add UserProfileView and UserProfileViewModel for iOS - Implement user library API endpoint (/api/users/[username]/library) - Add DELETE /api/progress/[slug] endpoint for removing books from library - Integrate subscription feed in home API - Update Xcode project with new profile components
This commit is contained in:
@@ -127,6 +127,14 @@ async function pbPatch(path: string, body: unknown): Promise<Response> {
|
||||
});
|
||||
}
|
||||
|
||||
async function pbDelete(path: string): Promise<Response> {
|
||||
const token = await getToken();
|
||||
return fetch(`${PB_URL}${path}`, {
|
||||
method: 'DELETE',
|
||||
headers: { Authorization: `Bearer ${token}` }
|
||||
});
|
||||
}
|
||||
|
||||
interface PBList<T> {
|
||||
items: T[];
|
||||
totalItems: number;
|
||||
@@ -286,10 +294,41 @@ export async function setProgress(
|
||||
if (!res.ok) {
|
||||
const body = await res.text().catch(() => '');
|
||||
log.error('pocketbase', 'setProgress POST failed', { slug, chapter, status: res.status, body });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete progress entry for a specific book (removes from library/continue reading).
|
||||
*/
|
||||
export async function deleteProgress(
|
||||
sessionId: string,
|
||||
slug: string,
|
||||
userId?: string
|
||||
): Promise<void> {
|
||||
const existing = await listOne<Progress & { id: string }>(
|
||||
'progress',
|
||||
progressFilter(sessionId, slug, userId)
|
||||
);
|
||||
|
||||
if (!existing) {
|
||||
log.debug('pocketbase', 'deleteProgress: no record found', { sessionId, slug, userId });
|
||||
return;
|
||||
}
|
||||
|
||||
const res = await pbDelete(`/api/collections/progress/records/${existing.id}`);
|
||||
if (!res.ok) {
|
||||
const body = await res.text().catch(() => '');
|
||||
log.error('pocketbase', 'deleteProgress failed', {
|
||||
slug,
|
||||
id: existing.id,
|
||||
status: res.status,
|
||||
body
|
||||
});
|
||||
throw new Error(`Failed to delete progress: ${res.status}`);
|
||||
}
|
||||
log.info('pocketbase', 'deleteProgress success', { slug, id: existing.id });
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge anonymous session progress into a user account on login/register.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user