feat: Implement person management features

- Added hooks for listing, creating, updating, deleting, sharing, and merging people.
- Introduced a new route for person details and media.
- Implemented clustering faces functionality.
- Created services for person-related API interactions.

feat: Introduce tag management functionality

- Added hooks for listing, adding, and removing tags from media.
- Created services for tag-related API interactions.

feat: Enhance user authentication handling

- Added a hook to fetch current user details.
- Updated auth storage to manage user state more effectively.

feat: Update album management features

- Enhanced album service to return created album details.
- Updated API handlers to return album responses upon creation.
- Modified album repository to return created album.

feat: Implement media management improvements

- Added media details fetching and processing of media URLs.
- Enhanced media upload functionality to return processed media.

feat: Introduce face management features

- Added services for listing faces for media and assigning faces to persons.

fix: Update API client to clear authentication state on 401 errors.
This commit is contained in:
2025-11-16 02:24:50 +01:00
parent f41a3169e9
commit 94b184d3b0
34 changed files with 1300 additions and 281 deletions

View File

@@ -0,0 +1,114 @@
import type {
Media,
PaginatedResponse,
Person,
PersonPermission,
} from "@/domain/types";
import apiClient from "@/services/api-client";
import { processMediaUrls } from "./media-service"; // We can import the helper
// --- Types ---
export type CreatePersonPayload = {
name: string;
};
export type UpdatePersonPayload = {
name: string;
};
export type SharePersonPayload = {
target_user_id: string;
permission: PersonPermission;
};
export type UnsharePersonPayload = {
target_user_id: string;
};
export type MergePersonPayload = {
source_person_id: string;
};
export type SetPersonThumbnailPayload = {
face_region_id: string;
};
export type ListPeopleParams = {
personId: string,
page: number;
limit: number;
};
// --- Service Functions ---
export const listPeople = async (): Promise<Person[]> => {
const { data } = await apiClient.get("/people");
return data;
};
export const getPerson = async (personId: string): Promise<Person> => {
const { data } = await apiClient.get(`/people/${personId}`);
return data;
};
export const createPerson = async (
payload: CreatePersonPayload,
): Promise<Person> => {
const { data } = await apiClient.post("/people", payload);
return data;
};
export const updatePerson = async (
personId: string,
payload: UpdatePersonPayload,
): Promise<Person> => {
const { data } = await apiClient.put(`/people/${personId}`, payload);
return data;
};
export const deletePerson = async (personId: string): Promise<void> => {
await apiClient.delete(`/people/${personId}`);
};
export const listMediaForPerson = async (
{ personId, page, limit }: ListPeopleParams
): Promise<PaginatedResponse<Media>> => {
const { data } = await apiClient.get(`/people/${personId}/media`, {
params: { page, limit },
});
data.data = data.data.map(processMediaUrls);
return data;
};
export const sharePerson = async (
personId: string,
payload: SharePersonPayload,
): Promise<void> => {
await apiClient.post(`/people/${personId}/share`, payload);
};
export const unsharePerson = async (
personId: string,
payload: UnsharePersonPayload,
): Promise<void> => {
await apiClient.delete(`/people/${personId}/share`, { data: payload });
};
export const mergePerson = async (
targetPersonId: string,
payload: MergePersonPayload,
): Promise<void> => {
await apiClient.post(`/people/${targetPersonId}/merge`, payload);
};
export const setPersonThumbnail = async (
personId: string,
payload: SetPersonThumbnailPayload,
): Promise<void> => {
await apiClient.put(`/people/${personId}/thumbnail`, payload);
};
export const clusterFaces = async (): Promise<void> => {
await apiClient.post("/people/cluster");
};