diff --git a/app/api/openapi.json b/app/api/openapi.json index a1207e4..403e09e 100644 --- a/app/api/openapi.json +++ b/app/api/openapi.json @@ -48,17 +48,13 @@ "name": "Locale", "description": "Locale selection endpoints (under /api/v1/restricted/langs-and-countries, requires authentication)" }, - { - "name": "Repo", - "description": "Repository time tracking data endpoints (under /api/v1/restricted/repo, requires authentication)" - }, - { - "name": "Admin", - "description": "Admin-only endpoints" - }, { "name": "Settings", "description": "Application settings and configuration endpoints" + }, + { + "name": "Carts", + "description": "Shopping cart management endpoints (under /api/v1/restricted/carts, requires authentication)" } ], "paths": { @@ -629,6 +625,41 @@ } } }, + "/api/v1/public/auth/update-choice": { + "post": { + "tags": ["Auth"], + "summary": "Update JWT token choice", + "description": "Updates the user's JWT token preference or refreshes the token. Requires authentication.", + "operationId": "updateChoice", + "security": [ + { + "CookieAuth": [] + } + ], + "responses": { + "200": { + "description": "Token choice updated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiResponse" + } + } + } + }, + "401": { + "description": "Not authenticated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, "/api/v1/public/auth/google": { "get": { "tags": ["Auth"], @@ -733,292 +764,6 @@ } } }, - "/api/v1/restricted/repo/get-repos": { - "get": { - "tags": ["Repo"], - "summary": "Get accessible repositories", - "description": "Returns a list of repository IDs that the authenticated user has access to.", - "operationId": "getRepos", - "security": [ - { - "CookieAuth": [] - } - ], - "responses": { - "200": { - "description": "List of repository IDs", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "integer", - "format": "uint" - }, - "example": [1, 2, 5] - } - } - } - }, - "400": { - "description": "Invalid user session", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "401": { - "description": "Not authenticated", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - } - } - }, - "/api/v1/restricted/repo/get-years": { - "get": { - "tags": ["Repo"], - "summary": "Get available years for a repository", - "description": "Returns a list of years for which tracked time data exists in the given repository. User must have access to the repository.", - "operationId": "getYears", - "security": [ - { - "CookieAuth": [] - } - ], - "parameters": [ - { - "name": "repoID", - "in": "query", - "description": "Repository ID", - "required": true, - "schema": { - "type": "integer", - "format": "uint" - } - } - ], - "responses": { - "200": { - "description": "List of years with tracked time data", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "integer", - "format": "uint" - }, - "example": [2023, 2024, 2025] - } - } - } - }, - "400": { - "description": "Invalid repoID parameter or user does not have access to the repository", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "401": { - "description": "Not authenticated", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - } - } - }, - "/api/v1/restricted/repo/get-quarters": { - "get": { - "tags": ["Repo"], - "summary": "Get quarterly time data for a repository", - "description": "Returns time tracked per quarter for the given repository and year. All 4 quarters are returned; quarters with no data have time=0. User must have access to the repository.", - "operationId": "getQuarters", - "security": [ - { - "CookieAuth": [] - } - ], - "parameters": [ - { - "name": "repoID", - "in": "query", - "description": "Repository ID", - "required": true, - "schema": { - "type": "integer", - "format": "uint" - } - }, - { - "name": "year", - "in": "query", - "description": "Year to retrieve quarterly data for", - "required": true, - "schema": { - "type": "integer", - "format": "uint", - "example": 2024 - } - } - ], - "responses": { - "200": { - "description": "Quarterly time data", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/QuarterData" - } - } - } - } - }, - "400": { - "description": "Invalid repoID or year parameter, or user does not have access to the repository", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "401": { - "description": "Not authenticated", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - } - } - }, - "/api/v1/restricted/repo/get-issues": { - "get": { - "tags": ["Repo"], - "summary": "Get issues with time summaries", - "description": "Returns a paginated list of issues with time tracking summaries for the given repository, year, and quarter. User must have access to the repository.", - "operationId": "getIssues", - "security": [ - { - "CookieAuth": [] - } - ], - "parameters": [ - { - "name": "repoID", - "in": "query", - "description": "Repository ID", - "required": true, - "schema": { - "type": "integer", - "format": "uint" - } - }, - { - "name": "year", - "in": "query", - "description": "Year to filter issues by", - "required": true, - "schema": { - "type": "integer", - "format": "uint", - "example": 2024 - } - }, - { - "name": "quarter", - "in": "query", - "description": "Quarter number (1-4) to filter issues by", - "required": true, - "schema": { - "type": "integer", - "format": "uint", - "minimum": 1, - "maximum": 4, - "example": 2 - } - }, - { - "name": "page_number", - "in": "query", - "description": "Page number for pagination (1-based)", - "required": true, - "schema": { - "type": "integer", - "format": "uint", - "example": 1 - } - }, - { - "name": "elements_per_page", - "in": "query", - "description": "Number of items per page", - "required": true, - "schema": { - "type": "integer", - "format": "uint", - "example": 30 - } - } - ], - "responses": { - "200": { - "description": "Paginated list of issues with time summaries", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PaginatedIssues" - } - } - } - }, - "400": { - "description": "Invalid parameters or user does not have access to the repository", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "401": { - "description": "Not authenticated", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - } - } - }, "/api/v1/settings": { "get": { "tags": ["Settings"], @@ -1043,7 +788,7 @@ "get": { "tags": ["Products"], "summary": "Get product listing", - "description": "Returns a paginated list of products with their basic information. Supports filtering via query parameters with operators (e.g., product_id_eq=12, name=~gold). Use sort parameter for ordering. Requires authentication.", + "description": "Returns a paginated list of products with their basic information. Supports filtering via query parameters with operators (e.g., product_id_eq=12, name=~wałek). Use sort parameter for ordering. Requires authentication.", "operationId": "getProductListing", "security": [ { @@ -1093,11 +838,10 @@ { "name": "name", "in": "query", - "description": "Filter by product name using LIKE (case-insensitive). Use ~ prefix for partial match (e.g., '~gold')", + "description": "Filter by product name using LIKE (case-insensitive). Use ~ prefix for partial match (e.g., '~wałek')", "required": false, "schema": { - "type": "string", - "example": "~gold" + "type": "string" } }, { @@ -1767,6 +1511,280 @@ } } } + }, + "/api/v1/restricted/carts/add-new-cart": { + "get": { + "tags": ["Carts"], + "summary": "Create a new cart", + "description": "Creates a new shopping cart for the authenticated user. Requires authentication.", + "operationId": "addNewCart", + "security": [ + { + "CookieAuth": [] + } + ], + "responses": { + "200": { + "description": "Cart created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiResponse" + } + } + } + }, + "401": { + "description": "Not authenticated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/restricted/carts/change-cart-name": { + "get": { + "tags": ["Carts"], + "summary": "Change cart name", + "description": "Updates the name of an existing cart. Requires authentication.", + "operationId": "changeCartName", + "security": [ + { + "CookieAuth": [] + } + ], + "parameters": [ + { + "name": "cart_id", + "in": "query", + "description": "ID of the cart to rename", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "new_name", + "in": "query", + "description": "New name for the cart", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Cart name updated successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiResponse" + } + } + } + }, + "400": { + "description": "Invalid request parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Not authenticated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/restricted/carts/retrieve-carts-info": { + "get": { + "tags": ["Carts"], + "summary": "Retrieve all carts info", + "description": "Returns information about all carts belonging to the authenticated user. Requires authentication.", + "operationId": "retrieveCartsInfo", + "security": [ + { + "CookieAuth": [] + } + ], + "responses": { + "200": { + "description": "Carts info retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiResponse" + } + } + } + }, + "401": { + "description": "Not authenticated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/restricted/carts/retrieve-cart": { + "get": { + "tags": ["Carts"], + "summary": "Retrieve cart details", + "description": "Returns detailed contents of a specific cart. Requires authentication.", + "operationId": "retrieveCart", + "security": [ + { + "CookieAuth": [] + } + ], + "parameters": [ + { + "name": "cart_id", + "in": "query", + "description": "ID of the cart to retrieve", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Cart retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiResponse" + } + } + } + }, + "400": { + "description": "Invalid request parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Not authenticated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/restricted/carts/add-product-to-cart": { + "get": { + "tags": ["Carts"], + "summary": "Add product to cart", + "description": "Adds a product to the specified cart. Requires authentication.", + "operationId": "addProductToCart", + "security": [ + { + "CookieAuth": [] + } + ], + "parameters": [ + { + "name": "cart_id", + "in": "query", + "description": "ID of the cart to add product to", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "product_id", + "in": "query", + "description": "ID of the product to add", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "product_attribute_id", + "in": "query", + "description": "ID of the product attribute (optional, for product variants)", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "name": "amount", + "in": "query", + "description": "Quantity to add", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Product added to cart successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiResponse" + } + } + } + }, + "400": { + "description": "Invalid request parameters", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "Not authenticated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } } }, "components": { diff --git a/app/model/product.go b/app/model/product.go index c0b6331..7705238 100644 --- a/app/model/product.go +++ b/app/model/product.go @@ -69,7 +69,7 @@ type ProductInList struct { CategoryName string `gorm:"column:category_name" json:"category_name" form:"category_name"` Reference string `gorm:"column:reference" json:"reference"` VariantsNumber uint `gorm:"column:variants_number" json:"variants_number"` - Quantity uint `gorm:"column:quantity" json:"quantity"` + Quantity int64 `gorm:"column:quantity" json:"quantity"` } type ProductFilters struct { diff --git a/bo/src/components/customer/PageCustomerData.vue b/bo/src/components/customer/PageCustomerData.vue index dbe2448..3fb35cc 100644 --- a/bo/src/components/customer/PageCustomerData.vue +++ b/bo/src/components/customer/PageCustomerData.vue @@ -1,89 +1,102 @@ diff --git a/bo/src/components/customer/PageProductsList.vue b/bo/src/components/customer/PageProductsList.vue index d8bacfa..62630b4 100644 --- a/bo/src/components/customer/PageProductsList.vue +++ b/bo/src/components/customer/PageProductsList.vue @@ -35,7 +35,7 @@ - product image {{ @@ -49,6 +49,9 @@ +
+ +
No products found
@@ -59,17 +62,21 @@ \ No newline at end of file diff --git a/bo/src/views/RepoChartView.vue b/bo/src/views/RepoChartView.vue index 122d31b..ed81c31 100644 --- a/bo/src/views/RepoChartView.vue +++ b/bo/src/views/RepoChartView.vue @@ -238,7 +238,7 @@ const columns = computed[]>(() => [
- +