diff --git a/openapi/openapi.json b/openapi/openapi.json deleted file mode 100644 index 5569195..0000000 --- a/openapi/openapi.json +++ /dev/null @@ -1,2234 +0,0 @@ -{ - "openapi": "3.1.0", - "info": { - "title": "Assets API", - "version": "0.1.0" - }, - "paths": { - "/api/auth/me": { - "get": { - "tags": [ - "auth" - ], - "summary": "Read Users Me", - "operationId": "read_users_me_api_auth_me_get", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/api__endpoints__auth__UserResponse" - } - } - } - } - }, - "security": [ - { - "OAuth2PasswordBearer": [] - } - ] - } - }, - "/api/auth/register": { - "post": { - "tags": [ - "auth" - ], - "summary": "Register", - "operationId": "register_api_auth_register_post", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserRegister" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": {} - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/api/auth/token": { - "post": { - "tags": [ - "auth" - ], - "summary": "Login For Access Token", - "operationId": "login_for_access_token_api_auth_token_post", - "requestBody": { - "content": { - "application/x-www-form-urlencoded": { - "schema": { - "$ref": "#/components/schemas/Body_login_for_access_token_api_auth_token_post" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Token" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/api/admin/approvals": { - "get": { - "tags": [ - "admin" - ], - "summary": "List Pending Users", - "operationId": "list_pending_users_api_admin_approvals_get", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/UserResponse" - }, - "type": "array", - "title": "Response List Pending Users Api Admin Approvals Get" - } - } - } - } - }, - "security": [ - { - "OAuth2PasswordBearer": [] - } - ] - } - }, - "/api/admin/approve/{username}": { - "post": { - "tags": [ - "admin" - ], - "summary": "Approve User", - "operationId": "approve_user_api_admin_approve__username__post", - "security": [ - { - "OAuth2PasswordBearer": [] - } - ], - "parameters": [ - { - "name": "username", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Username" - } - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": {} - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/api/admin/deny/{username}": { - "post": { - "tags": [ - "admin" - ], - "summary": "Deny User", - "operationId": "deny_user_api_admin_deny__username__post", - "security": [ - { - "OAuth2PasswordBearer": [] - } - ], - "parameters": [ - { - "name": "username", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Username" - } - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": {} - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/api/assets/{asset_id}": { - "get": { - "tags": [ - "Assets" - ], - "summary": "Get Asset", - "operationId": "get_asset_api_assets__asset_id__get", - "parameters": [ - { - "name": "asset_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Asset Id" - } - }, - { - "name": "thumbnail", - "in": "query", - "required": false, - "schema": { - "type": "boolean", - "default": false, - "title": "Thumbnail" - } - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": {} - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Assets" - ], - "summary": "Delete Asset", - "operationId": "delete_asset_api_assets__asset_id__delete", - "security": [ - { - "OAuth2PasswordBearer": [] - } - ], - "parameters": [ - { - "name": "asset_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Asset Id" - } - } - ], - "responses": { - "204": { - "description": "Successful Response" - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/api/assets": { - "get": { - "tags": [ - "Assets" - ], - "summary": "Get Assets", - "operationId": "get_assets_api_assets_get", - "security": [ - { - "OAuth2PasswordBearer": [] - } - ], - "parameters": [ - { - "name": "type", - "in": "query", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Type" - } - }, - { - "name": "limit", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "default": 10, - "title": "Limit" - } - }, - { - "name": "offset", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "default": 0, - "title": "Offset" - } - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AssetsResponse" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/api/assets/upload": { - "post": { - "tags": [ - "Assets" - ], - "summary": "Upload Asset", - "operationId": "upload_asset_api_assets_upload_post", - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "$ref": "#/components/schemas/Body_upload_asset_api_assets_upload_post" - } - } - }, - "required": true - }, - "responses": { - "201": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AssetResponse" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - }, - "security": [ - { - "OAuth2PasswordBearer": [] - } - ] - } - }, - "/api/assets/regenerate_thumbnails": { - "post": { - "tags": [ - "Assets" - ], - "summary": "Regenerate Thumbnails", - "description": "Regenerates thumbnails for all existing image assets that don't have one.", - "operationId": "regenerate_thumbnails_api_assets_regenerate_thumbnails_post", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": {} - } - } - } - }, - "security": [ - { - "OAuth2PasswordBearer": [] - } - ] - } - }, - "/api/assets/migrate_to_minio": { - "post": { - "tags": [ - "Assets" - ], - "summary": "Migrate To Minio", - "description": "Migrates assets from MongoDB to MinIO.", - "operationId": "migrate_to_minio_api_assets_migrate_to_minio_post", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": {} - } - } - } - }, - "security": [ - { - "OAuth2PasswordBearer": [] - } - ] - } - }, - "/api/characters/": { - "get": { - "tags": [ - "Characters" - ], - "summary": "Get Characters", - "operationId": "get_characters_api_characters__get", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/Character" - }, - "type": "array", - "title": "Response Get Characters Api Characters Get" - } - } - } - } - }, - "security": [ - { - "OAuth2PasswordBearer": [] - } - ] - } - }, - "/api/characters/{character_id}/assets": { - "get": { - "tags": [ - "Characters" - ], - "summary": "Get Character Assets", - "operationId": "get_character_assets_api_characters__character_id__assets_get", - "security": [ - { - "OAuth2PasswordBearer": [] - } - ], - "parameters": [ - { - "name": "character_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Character Id" - } - }, - { - "name": "limit", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "default": 10, - "title": "Limit" - } - }, - { - "name": "offset", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "default": 0, - "title": "Offset" - } - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AssetsResponse" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/api/characters/{character_id}": { - "get": { - "tags": [ - "Characters" - ], - "summary": "Get Character By Id", - "operationId": "get_character_by_id_api_characters__character_id__get", - "security": [ - { - "OAuth2PasswordBearer": [] - } - ], - "parameters": [ - { - "name": "character_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Character Id" - } - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Character" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/api/characters/{character_id}/_run": { - "post": { - "tags": [ - "Characters" - ], - "summary": "Post Character Generation", - "operationId": "post_character_generation_api_characters__character_id___run_post", - "security": [ - { - "OAuth2PasswordBearer": [] - } - ], - "parameters": [ - { - "name": "character_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Character Id" - } - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GenerationRequest" - } - } - } - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GenerationResponse" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/api/generations/prompt-assistant": { - "post": { - "tags": [ - "Generation" - ], - "summary": "Ask Prompt Assistant", - "operationId": "ask_prompt_assistant_api_generations_prompt_assistant_post", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PromptRequest" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PromptResponse" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - }, - "security": [ - { - "OAuth2PasswordBearer": [] - } - ] - } - }, - "/api/generations/prompt-from-image": { - "post": { - "tags": [ - "Generation" - ], - "summary": "Prompt From Image", - "operationId": "prompt_from_image_api_generations_prompt_from_image_post", - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "$ref": "#/components/schemas/Body_prompt_from_image_api_generations_prompt_from_image_post" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PromptResponse" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - }, - "security": [ - { - "OAuth2PasswordBearer": [] - } - ] - } - }, - "/api/generations": { - "get": { - "tags": [ - "Generation" - ], - "summary": "Get Generations", - "operationId": "get_generations_api_generations_get", - "security": [ - { - "OAuth2PasswordBearer": [] - } - ], - "parameters": [ - { - "name": "character_id", - "in": "query", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Character Id" - } - }, - { - "name": "limit", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "default": 10, - "title": "Limit" - } - }, - { - "name": "offset", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "default": 0, - "title": "Offset" - } - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GenerationsResponse" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/api/generations/_run": { - "post": { - "tags": [ - "Generation" - ], - "summary": "Post Generation", - "operationId": "post_generation_api_generations__run_post", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GenerationRequest" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GenerationResponse" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - }, - "security": [ - { - "OAuth2PasswordBearer": [] - } - ] - } - }, - "/api/generations/{generation_id}": { - "get": { - "tags": [ - "Generation" - ], - "summary": "Get Generation", - "operationId": "get_generation_api_generations__generation_id__get", - "security": [ - { - "OAuth2PasswordBearer": [] - } - ], - "parameters": [ - { - "name": "generation_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Generation Id" - } - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GenerationResponse" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Generation" - ], - "summary": "Delete Generation", - "operationId": "delete_generation_api_generations__generation_id__delete", - "security": [ - { - "OAuth2PasswordBearer": [] - } - ], - "parameters": [ - { - "name": "generation_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Generation Id" - } - } - ], - "responses": { - "204": { - "description": "Successful Response" - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/api/generations/running": { - "get": { - "tags": [ - "Generation" - ], - "summary": "Get Running Generations", - "operationId": "get_running_generations_api_generations_running_get", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": {} - } - } - } - }, - "security": [ - { - "OAuth2PasswordBearer": [] - } - ] - } - }, - "/albums/": { - "post": { - "tags": [ - "Albums" - ], - "summary": "Create Album", - "operationId": "create_album_albums__post", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AlbumCreateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AlbumResponse" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - }, - "get": { - "tags": [ - "Albums" - ], - "summary": "Get Albums", - "operationId": "get_albums_albums__get", - "parameters": [ - { - "name": "limit", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "default": 10, - "title": "Limit" - } - }, - { - "name": "offset", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "default": 0, - "title": "Offset" - } - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AlbumResponse" - }, - "title": "Response Get Albums Albums Get" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/albums/{album_id}": { - "get": { - "tags": [ - "Albums" - ], - "summary": "Get Album", - "operationId": "get_album_albums__album_id__get", - "parameters": [ - { - "name": "album_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Album Id" - } - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AlbumResponse" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - }, - "put": { - "tags": [ - "Albums" - ], - "summary": "Update Album", - "operationId": "update_album_albums__album_id__put", - "parameters": [ - { - "name": "album_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Album Id" - } - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AlbumUpdateRequest" - } - } - } - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AlbumResponse" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Albums" - ], - "summary": "Delete Album", - "operationId": "delete_album_albums__album_id__delete", - "parameters": [ - { - "name": "album_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Album Id" - } - } - ], - "responses": { - "204": { - "description": "Successful Response" - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/albums/{album_id}/generations/{generation_id}": { - "post": { - "tags": [ - "Albums" - ], - "summary": "Add Generation To Album", - "operationId": "add_generation_to_album_albums__album_id__generations__generation_id__post", - "parameters": [ - { - "name": "album_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Album Id" - } - }, - { - "name": "generation_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Generation Id" - } - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": {} - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Albums" - ], - "summary": "Remove Generation From Album", - "operationId": "remove_generation_from_album_albums__album_id__generations__generation_id__delete", - "parameters": [ - { - "name": "album_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Album Id" - } - }, - { - "name": "generation_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Generation Id" - } - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": {} - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/albums/{album_id}/generations": { - "get": { - "tags": [ - "Albums" - ], - "summary": "Get Album Generations", - "operationId": "get_album_generations_albums__album_id__generations_get", - "parameters": [ - { - "name": "album_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Album Id" - } - }, - { - "name": "limit", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "default": 10, - "title": "Limit" - } - }, - { - "name": "offset", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "default": 0, - "title": "Offset" - } - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/GenerationResponse" - }, - "title": "Response Get Album Generations Albums Album Id Generations Get" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "AlbumCreateRequest": { - "properties": { - "name": { - "type": "string", - "title": "Name" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Description" - } - }, - "type": "object", - "required": [ - "name" - ], - "title": "AlbumCreateRequest" - }, - "AlbumResponse": { - "properties": { - "id": { - "type": "string", - "title": "Id" - }, - "name": { - "type": "string", - "title": "Name" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Description" - }, - "generation_ids": { - "items": { - "type": "string" - }, - "type": "array", - "title": "Generation Ids", - "default": [] - } - }, - "type": "object", - "required": [ - "id", - "name" - ], - "title": "AlbumResponse" - }, - "AlbumUpdateRequest": { - "properties": { - "name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Name" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Description" - } - }, - "type": "object", - "title": "AlbumUpdateRequest" - }, - "AspectRatios": { - "type": "string", - "enum": [ - "NINESIXTEEN", - "SIXTEENNINE", - "THREEFOUR", - "FOURTHREE" - ], - "title": "AspectRatios" - }, - "AssetResponse": { - "properties": { - "id": { - "type": "string", - "title": "Id" - }, - "name": { - "type": "string", - "title": "Name" - }, - "type": { - "type": "string", - "title": "Type" - }, - "content_type": { - "type": "string", - "title": "Content Type" - }, - "linked_char_id": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Linked Char Id" - }, - "created_at": { - "type": "string", - "format": "date-time", - "title": "Created At" - }, - "url": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Url" - } - }, - "type": "object", - "required": [ - "id", - "name", - "type", - "content_type", - "created_at" - ], - "title": "AssetResponse" - }, - "AssetsResponse": { - "properties": { - "assets": { - "items": { - "$ref": "#/components/schemas/AssetResponse" - }, - "type": "array", - "title": "Assets" - }, - "total_count": { - "type": "integer", - "title": "Total Count" - } - }, - "type": "object", - "required": [ - "assets", - "total_count" - ], - "title": "AssetsResponse" - }, - "Body_login_for_access_token_api_auth_token_post": { - "properties": { - "grant_type": { - "anyOf": [ - { - "type": "string", - "pattern": "^password$" - }, - { - "type": "null" - } - ], - "title": "Grant Type" - }, - "username": { - "type": "string", - "title": "Username" - }, - "password": { - "type": "string", - "format": "password", - "title": "Password" - }, - "scope": { - "type": "string", - "title": "Scope", - "default": "" - }, - "client_id": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Client Id" - }, - "client_secret": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "format": "password", - "title": "Client Secret" - } - }, - "type": "object", - "required": [ - "username", - "password" - ], - "title": "Body_login_for_access_token_api_auth_token_post" - }, - "Body_prompt_from_image_api_generations_prompt_from_image_post": { - "properties": { - "prompt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Prompt" - }, - "images": { - "items": { - "type": "string", - "format": "binary" - }, - "type": "array", - "title": "Images" - } - }, - "type": "object", - "required": [ - "images" - ], - "title": "Body_prompt_from_image_api_generations_prompt_from_image_post" - }, - "Body_upload_asset_api_assets_upload_post": { - "properties": { - "file": { - "type": "string", - "format": "binary", - "title": "File" - }, - "linked_char_id": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Linked Char Id" - } - }, - "type": "object", - "required": [ - "file" - ], - "title": "Body_upload_asset_api_assets_upload_post" - }, - "Character": { - "properties": { - "id": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Id" - }, - "name": { - "type": "string", - "title": "Name" - }, - "avatar_image": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Avatar Image" - }, - "character_image_data": { - "anyOf": [ - { - "type": "string", - "format": "binary" - }, - { - "type": "null" - } - ], - "title": "Character Image Data" - }, - "character_image_doc_tg_id": { - "type": "string", - "title": "Character Image Doc Tg Id" - }, - "character_image_tg_id": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Character Image Tg Id" - }, - "character_bio": { - "type": "string", - "title": "Character Bio" - } - }, - "type": "object", - "required": [ - "id", - "name", - "character_image_doc_tg_id", - "character_image_tg_id", - "character_bio" - ], - "title": "Character" - }, - "GenerationRequest": { - "properties": { - "linked_character_id": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Linked Character Id" - }, - "aspect_ratio": { - "$ref": "#/components/schemas/AspectRatios", - "default": "NINESIXTEEN" - }, - "quality": { - "$ref": "#/components/schemas/Quality", - "default": "ONEK" - }, - "prompt": { - "type": "string", - "title": "Prompt" - }, - "telegram_id": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "title": "Telegram Id" - }, - "use_profile_image": { - "type": "boolean", - "title": "Use Profile Image", - "default": true - }, - "assets_list": { - "items": { - "type": "string" - }, - "type": "array", - "title": "Assets List" - } - }, - "type": "object", - "required": [ - "prompt", - "assets_list" - ], - "title": "GenerationRequest" - }, - "GenerationResponse": { - "properties": { - "id": { - "type": "string", - "title": "Id" - }, - "status": { - "$ref": "#/components/schemas/GenerationStatus" - }, - "failed_reason": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Failed Reason" - }, - "linked_character_id": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Linked Character Id" - }, - "aspect_ratio": { - "$ref": "#/components/schemas/AspectRatios" - }, - "quality": { - "$ref": "#/components/schemas/Quality" - }, - "prompt": { - "type": "string", - "title": "Prompt" - }, - "tech_prompt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Tech Prompt" - }, - "assets_list": { - "items": { - "type": "string" - }, - "type": "array", - "title": "Assets List" - }, - "result_list": { - "items": { - "type": "string" - }, - "type": "array", - "title": "Result List", - "default": [] - }, - "result": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Result" - }, - "execution_time_seconds": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "title": "Execution Time Seconds" - }, - "api_execution_time_seconds": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "title": "Api Execution Time Seconds" - }, - "token_usage": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "title": "Token Usage" - }, - "input_token_usage": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "title": "Input Token Usage" - }, - "output_token_usage": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "title": "Output Token Usage" - }, - "progress": { - "type": "integer", - "title": "Progress", - "default": 0 - }, - "created_at": { - "type": "string", - "format": "date-time", - "title": "Created At", - "default": "2026-02-08T17:27:29.368203Z" - }, - "updated_at": { - "type": "string", - "format": "date-time", - "title": "Updated At", - "default": "2026-02-08T17:27:29.368207Z" - } - }, - "type": "object", - "required": [ - "id", - "status", - "aspect_ratio", - "quality", - "prompt", - "assets_list" - ], - "title": "GenerationResponse" - }, - "GenerationStatus": { - "type": "string", - "enum": [ - "running", - "done", - "failed" - ], - "title": "GenerationStatus" - }, - "GenerationsResponse": { - "properties": { - "generations": { - "items": { - "$ref": "#/components/schemas/GenerationResponse" - }, - "type": "array", - "title": "Generations" - }, - "total_count": { - "type": "integer", - "title": "Total Count" - } - }, - "type": "object", - "required": [ - "generations", - "total_count" - ], - "title": "GenerationsResponse" - }, - "HTTPValidationError": { - "properties": { - "detail": { - "items": { - "$ref": "#/components/schemas/ValidationError" - }, - "type": "array", - "title": "Detail" - } - }, - "type": "object", - "title": "HTTPValidationError" - }, - "PromptRequest": { - "properties": { - "prompt": { - "type": "string", - "title": "Prompt" - }, - "linked_assets": { - "items": { - "type": "string" - }, - "type": "array", - "title": "Linked Assets", - "default": [] - } - }, - "type": "object", - "required": [ - "prompt" - ], - "title": "PromptRequest" - }, - "PromptResponse": { - "properties": { - "prompt": { - "type": "string", - "title": "Prompt" - } - }, - "type": "object", - "required": [ - "prompt" - ], - "title": "PromptResponse" - }, - "Quality": { - "type": "string", - "enum": [ - "ONEK", - "TWOK", - "FOURK" - ], - "title": "Quality" - }, - "Token": { - "properties": { - "access_token": { - "type": "string", - "title": "Access Token" - }, - "token_type": { - "type": "string", - "title": "Token Type" - } - }, - "type": "object", - "required": [ - "access_token", - "token_type" - ], - "title": "Token" - }, - "UserRegister": { - "properties": { - "username": { - "type": "string", - "title": "Username" - }, - "password": { - "type": "string", - "title": "Password" - }, - "full_name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Full Name" - } - }, - "type": "object", - "required": [ - "username", - "password" - ], - "title": "UserRegister" - }, - "UserResponse": { - "properties": { - "username": { - "type": "string", - "title": "Username" - }, - "full_name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Full Name" - }, - "status": { - "type": "string", - "title": "Status" - }, - "created_at": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Created At" - }, - "is_admin": { - "type": "boolean", - "title": "Is Admin" - } - }, - "type": "object", - "required": [ - "username", - "status", - "is_admin" - ], - "title": "UserResponse" - }, - "ValidationError": { - "properties": { - "loc": { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array", - "title": "Location" - }, - "msg": { - "type": "string", - "title": "Message" - }, - "type": { - "type": "string", - "title": "Error Type" - } - }, - "type": "object", - "required": [ - "loc", - "msg", - "type" - ], - "title": "ValidationError" - }, - "api__endpoints__auth__UserResponse": { - "properties": { - "username": { - "type": "string", - "title": "Username" - }, - "full_name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Full Name" - }, - "status": { - "type": "string", - "title": "Status" - }, - "is_admin": { - "type": "boolean", - "title": "Is Admin", - "default": false - } - }, - "type": "object", - "required": [ - "username", - "status" - ], - "title": "UserResponse" - } - }, - "securitySchemes": { - "OAuth2PasswordBearer": { - "type": "oauth2", - "flows": { - "password": { - "scopes": {}, - "tokenUrl": "/api/auth/token" - } - } - } - } - } -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a4faf7a..288f723 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@primeuix/themes": "^2.0.3", "@primevue/themes": "^4.5.4", "axios": "^1.13.4", + "jszip": "^3.10.1", "pinia": "^3.0.4", "primeicons": "^7.0.0", "primevue": "^4.5.4", @@ -3896,6 +3897,12 @@ "url": "https://opencollective.com/core-js" } }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -4861,6 +4868,18 @@ "dev": true, "license": "ISC" }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "license": "MIT" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -5474,6 +5493,18 @@ "node": ">=0.10.0" } }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, "node_modules/kolorist": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", @@ -5491,6 +5522,15 @@ "node": ">=6" } }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, "node_modules/lightningcss": { "version": "1.30.2", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", @@ -6058,6 +6098,12 @@ "dev": true, "license": "BlueOak-1.0.0" }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "license": "(MIT AND Zlib)" + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -6244,6 +6290,12 @@ "node": ">=12.11.0" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -6286,6 +6338,33 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, "node_modules/readdirp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", @@ -6647,6 +6726,12 @@ "node": ">= 0.4" } }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -6862,6 +6947,21 @@ "node": ">= 0.4" } }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -7464,6 +7564,12 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, "node_modules/vite": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", diff --git a/package.json b/package.json index aa7833a..4a80fe5 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@primeuix/themes": "^2.0.3", "@primevue/themes": "^4.5.4", "axios": "^1.13.4", + "jszip": "^3.10.1", "pinia": "^3.0.4", "primeicons": "^7.0.0", "primevue": "^4.5.4", diff --git a/src/components/AppSidebar.vue b/src/components/AppSidebar.vue index 26b651b..6a2e6b8 100644 --- a/src/components/AppSidebar.vue +++ b/src/components/AppSidebar.vue @@ -70,11 +70,12 @@ const isActive = (path) => { const navItems = computed(() => { const items = [ - { path: '/', icon: '🏠', tooltip: 'Home' }, + // { path: '/', icon: '🏠', tooltip: 'Home' }, { path: '/projects', icon: '📂', tooltip: 'Projects' }, + { path: '/content-plan', icon: '📅', tooltip: 'Plan' }, { path: '/ideas', icon: '💡', tooltip: 'Ideas' }, { path: '/flexible', icon: '🖌️', tooltip: 'Flexible' }, - { path: '/albums', icon: '🖼️', tooltip: 'Library' }, + // { path: '/albums', icon: '🖼️', tooltip: 'Library' }, { path: '/characters', icon: '👥', tooltip: 'Characters' } ] diff --git a/src/router/index.js b/src/router/index.js index 1b6d3c4..4ba102c 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -57,6 +57,11 @@ const router = createRouter({ name: 'flexible', component: () => import('../views/FlexibleGenerationView.vue') }, + { + path: '/content-plan', + name: 'content-plan', + component: () => import('../views/ContentPlanView.vue') + }, { path: '/albums', name: 'albums', diff --git a/src/services/postService.js b/src/services/postService.js new file mode 100644 index 0000000..be20b59 --- /dev/null +++ b/src/services/postService.js @@ -0,0 +1,24 @@ +import api from './api'; + +export const postService = { + getPosts: (dateFrom, dateTo) => { + const params = {}; + if (dateFrom) params.date_from = dateFrom; + if (dateTo) params.date_to = dateTo; + return api.get('/posts', { params }).then(r => r.data); + }, + + createPost: (data) => api.post('/posts', data).then(r => r.data), + + getPost: (id) => api.get(`/posts/${id}`).then(r => r.data), + + updatePost: (id, data) => api.put(`/posts/${id}`, data).then(r => r.data), + + deletePost: (id) => api.delete(`/posts/${id}`).then(r => r.data), + + addGenerations: (postId, generationIds) => + api.post(`/posts/${postId}/generations`, { generation_ids: generationIds }).then(r => r.data), + + removeGeneration: (postId, generationId) => + api.delete(`/posts/${postId}/generations/${generationId}`).then(r => r.data), +}; diff --git a/src/stores/ideas.js b/src/stores/ideas.js index fb74b4b..70c98c5 100644 --- a/src/stores/ideas.js +++ b/src/stores/ideas.js @@ -32,13 +32,13 @@ export const useIdeaStore = defineStore('ideas', () => { loading.value = true; error.value = null; try { - await ideaService.createIdea(data); + const response = await ideaService.createIdea(data); await fetchIdeas(); // Refresh list - return true; + return response.data; } catch (err) { console.error('Error creating idea:', err); error.value = err.response?.data?.detail || 'Failed to create idea'; - return false; + return null; } finally { loading.value = false; } diff --git a/src/views/ContentPlanView.vue b/src/views/ContentPlanView.vue new file mode 100644 index 0000000..fe17fa4 --- /dev/null +++ b/src/views/ContentPlanView.vue @@ -0,0 +1,955 @@ + + + + + diff --git a/src/views/FlexibleGenerationView.vue b/src/views/FlexibleGenerationView.vue index 4f77e88..8a3c452 100644 --- a/src/views/FlexibleGenerationView.vue +++ b/src/views/FlexibleGenerationView.vue @@ -3,12 +3,14 @@ import { ref, onMounted, onBeforeUnmount, watch, computed } from 'vue' import { useRouter } from 'vue-router' import { dataService } from '../services/dataService' import { aiService } from '../services/aiService' +import { postService } from '../services/postService' import Button from 'primevue/button' import Textarea from 'primevue/textarea' import InputText from 'primevue/inputtext' import Dialog from 'primevue/dialog' import Checkbox from 'primevue/checkbox' import Dropdown from 'primevue/dropdown' +import DatePicker from 'primevue/datepicker' import MultiSelect from 'primevue/multiselect' import ProgressSpinner from 'primevue/progressspinner' import ProgressBar from 'primevue/progressbar' @@ -16,10 +18,122 @@ import Message from 'primevue/message' import Skeleton from 'primevue/skeleton' import { useAlbumStore } from '../stores/albums' +import { useToast } from 'primevue/usetoast' +import Toast from 'primevue/toast' const router = useRouter() const API_URL = import.meta.env.VITE_API_URL const albumStore = useAlbumStore() +const toast = useToast() + +// --- Multi-Select --- +const isSelectMode = ref(false) +const selectedAssetIds = ref(new Set()) +const isDownloading = ref(false) + +const toggleSelectMode = () => { + isSelectMode.value = !isSelectMode.value + if (!isSelectMode.value) selectedAssetIds.value = new Set() +} + +const toggleImageSelection = (assetId) => { + const s = new Set(selectedAssetIds.value) + if (s.has(assetId)) s.delete(assetId) + else s.add(assetId) + selectedAssetIds.value = s +} + +const selectAllImages = () => { + const s = new Set() + for (const gen of historyGenerations.value) { + if (gen.result_list) { + for (const id of gen.result_list) s.add(id) + } + } + selectedAssetIds.value = s +} + +const downloadSelected = async () => { + const ids = [...selectedAssetIds.value] + if (ids.length === 0) return + isDownloading.value = true + try { + const user = JSON.parse(localStorage.getItem('user')) + const headers = {} + if (user && user.access_token) headers['Authorization'] = `Bearer ${user.access_token}` + else if (user && user.token) headers['Authorization'] = `${user.tokenType} ${user.token}` + const projectId = localStorage.getItem('active_project_id') + if (projectId) headers['X-Project-ID'] = projectId + + const files = [] + for (const assetId of ids) { + const url = API_URL + '/assets/' + assetId + const resp = await fetch(url, { headers }) + const blob = await resp.blob() + files.push(new File([blob], assetId + '.png', { type: blob.type || 'image/png' })) + } + + const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) || navigator.maxTouchPoints > 1 + if (isMobile && navigator.canShare && navigator.canShare({ files })) { + await navigator.share({ files }) + } else { + for (let i = 0; i < files.length; i++) { + const file = files[i] + const a = document.createElement('a') + a.href = URL.createObjectURL(file) + a.download = file.name + document.body.appendChild(a) + a.click() + document.body.removeChild(a) + URL.revokeObjectURL(a.href) + if (i < files.length - 1) await new Promise(r => setTimeout(r, 300)) + } + } + toast.add({ severity: 'success', summary: `Скачано ${ids.length} файлов`, life: 2000 }) + } catch (e) { + console.error('Download failed', e) + toast.add({ severity: 'error', summary: 'Ошибка скачивания', life: 3000 }) + } finally { + isDownloading.value = false + } +} + +// --- Add to Content Plan --- +const showAddToPlanDialog = ref(false) +const planPostDate = ref(new Date()) +const planPostTopic = ref('') +const isSavingToPlan = ref(false) + +const openAddToPlan = () => { + planPostDate.value = new Date() + planPostTopic.value = '' + showAddToPlanDialog.value = true +} + +const confirmAddToPlan = async () => { + if (!planPostTopic.value.trim()) { + toast.add({ severity: 'warn', summary: 'Укажите тему', life: 2000 }) + return + } + isSavingToPlan.value = true + try { + const d = new Date(planPostDate.value); d.setHours(12, 0, 0, 0) + await postService.createPost({ + date: d.toISOString(), + topic: planPostTopic.value, + generation_ids: [...selectedAssetIds.value] + }) + toast.add({ severity: 'success', summary: 'Добавлено в контент-план', life: 2000 }) + showAddToPlanDialog.value = false + isSelectMode.value = false + selectedAssetIds.value = new Set() + } catch (e) { + console.error('Add to plan failed', e) + toast.add({ severity: 'error', summary: 'Ошибка', detail: 'Не удалось добавить', life: 3000 }) + } finally { + isSavingToPlan.value = false + } +} // --- State --- const prompt = ref('') @@ -731,6 +845,9 @@ const confirmAddToAlbum = async () => {