mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 10:42:57 +00:00
dev day #65
This commit is contained in:
@@ -14,7 +14,18 @@ export interface AIGenerateBlogResp {
|
||||
|
||||
export async function generateBlogAI(payload: AIGenerateBlogReq): Promise<AIGenerateBlogResp> {
|
||||
const { data } = await api.post<AIGenerateBlogResp>('/ai/blog/generate', payload);
|
||||
return data;
|
||||
|
||||
// Handle potential JSON string response from AI (defensive parsing)
|
||||
let parsedData = data;
|
||||
if (typeof data === 'string') {
|
||||
try {
|
||||
parsedData = JSON.parse(data);
|
||||
} catch {
|
||||
throw new Error('AI vrátila neplatný formát odpovědi');
|
||||
}
|
||||
}
|
||||
|
||||
return parsedData;
|
||||
}
|
||||
|
||||
export interface AIGenerateAboutReq {
|
||||
@@ -34,5 +45,16 @@ export interface AIGenerateAboutResp {
|
||||
|
||||
export async function generateAboutAI(payload: AIGenerateAboutReq): Promise<AIGenerateAboutResp> {
|
||||
const { data } = await api.post<AIGenerateAboutResp>('/ai/about/generate', payload);
|
||||
return data;
|
||||
|
||||
// Handle potential JSON string response from AI (defensive parsing)
|
||||
let parsedData = data;
|
||||
if (typeof data === 'string') {
|
||||
try {
|
||||
parsedData = JSON.parse(data);
|
||||
} catch {
|
||||
throw new Error('AI vrátila neplatný formát odpovědi');
|
||||
}
|
||||
}
|
||||
|
||||
return parsedData;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ export interface Article {
|
||||
image_url?: string;
|
||||
author?: { id: number; first_name?: string; last_name?: string; email: string };
|
||||
category_id?: number;
|
||||
category?: { id: number; name: string; description?: string; slug?: string; created_at?: string; updated_at?: string };
|
||||
category_name?: string;
|
||||
published?: boolean;
|
||||
featured?: boolean;
|
||||
created_at?: string;
|
||||
@@ -41,6 +43,7 @@ export interface Article {
|
||||
youtube_video_title?: string;
|
||||
youtube_video_url?: string;
|
||||
youtube_video_thumbnail?: string;
|
||||
attachments?: Array<{ name: string; url: string; mime_type?: string; size?: number }>;
|
||||
}
|
||||
|
||||
// --- Article ⇄ Match link ---
|
||||
@@ -139,6 +142,7 @@ export interface CreateArticlePayload {
|
||||
youtube_video_title?: string;
|
||||
youtube_video_url?: string;
|
||||
youtube_video_thumbnail?: string;
|
||||
attachments?: Array<{ name: string; url: string; mime_type?: string; size?: number }>;
|
||||
}
|
||||
|
||||
export async function createArticle(payload: CreateArticlePayload) {
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
import api from './api';
|
||||
|
||||
export interface ImageProcessRequest {
|
||||
image_url: string;
|
||||
operation?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
crop_x?: number;
|
||||
crop_y?: number;
|
||||
crop_width?: number;
|
||||
crop_height?: number;
|
||||
rotation?: number;
|
||||
flip_h?: boolean;
|
||||
flip_v?: boolean;
|
||||
brightness?: number;
|
||||
contrast?: number;
|
||||
saturation?: number;
|
||||
blur?: number;
|
||||
sharpen?: number;
|
||||
grayscale?: boolean;
|
||||
quality?: number;
|
||||
}
|
||||
|
||||
export interface QuickEditRequest {
|
||||
image_url: string;
|
||||
width?: number;
|
||||
rotation?: number;
|
||||
flip_h?: boolean;
|
||||
flip_v?: boolean;
|
||||
brightness?: number;
|
||||
contrast?: number;
|
||||
saturation?: number;
|
||||
grayscale?: boolean;
|
||||
quality?: number;
|
||||
}
|
||||
|
||||
export interface ImageProcessResponse {
|
||||
url: string;
|
||||
format?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process image with various operations (crop, resize, filters, etc.)
|
||||
*/
|
||||
export const processImage = async (request: ImageProcessRequest): Promise<ImageProcessResponse> => {
|
||||
const response = await api.post('/image-processing/process', request);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Quick edit for common operations in one call
|
||||
*/
|
||||
export const quickEditImage = async (request: QuickEditRequest): Promise<ImageProcessResponse> => {
|
||||
const response = await api.post('/image-processing/quick-edit', request);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Crop and upload image file
|
||||
*/
|
||||
export const cropAndUpload = async (
|
||||
file: File,
|
||||
cropData?: { x: number; y: number; width: number; height: number },
|
||||
quality = 85,
|
||||
maxWidth = 1500
|
||||
): Promise<ImageProcessResponse> => {
|
||||
const formData = new FormData();
|
||||
formData.append('image', file);
|
||||
|
||||
if (cropData) {
|
||||
formData.append('crop_data', JSON.stringify(cropData));
|
||||
}
|
||||
|
||||
formData.append('quality', quality.toString());
|
||||
formData.append('max_width', maxWidth.toString());
|
||||
|
||||
const response = await api.post('/image-processing/crop-upload', formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
});
|
||||
|
||||
return response.data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Resize image to specific width (maintains aspect ratio)
|
||||
*/
|
||||
export const resizeImage = async (imageUrl: string, width: number, quality = 85): Promise<ImageProcessResponse> => {
|
||||
return quickEditImage({
|
||||
image_url: imageUrl,
|
||||
width,
|
||||
quality,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply filters to image
|
||||
*/
|
||||
export const applyFilters = async (
|
||||
imageUrl: string,
|
||||
filters: {
|
||||
brightness?: number;
|
||||
contrast?: number;
|
||||
saturation?: number;
|
||||
blur?: number;
|
||||
grayscale?: boolean;
|
||||
},
|
||||
quality = 85
|
||||
): Promise<ImageProcessResponse> => {
|
||||
return quickEditImage({
|
||||
image_url: imageUrl,
|
||||
...filters,
|
||||
quality,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Rotate image (90, 180, 270 degrees)
|
||||
*/
|
||||
export const rotateImage = async (imageUrl: string, rotation: number, quality = 85): Promise<ImageProcessResponse> => {
|
||||
return quickEditImage({
|
||||
image_url: imageUrl,
|
||||
rotation,
|
||||
quality,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Flip image horizontally or vertically
|
||||
*/
|
||||
export const flipImage = async (
|
||||
imageUrl: string,
|
||||
flipH: boolean,
|
||||
flipV: boolean,
|
||||
quality = 85
|
||||
): Promise<ImageProcessResponse> => {
|
||||
return quickEditImage({
|
||||
image_url: imageUrl,
|
||||
flip_h: flipH,
|
||||
flip_v: flipV,
|
||||
quality,
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user