diff --git a/spec.json b/spec.json index e6566e8325cdbf7dd17a2bb0286b7fe42273b085..c73c99bf2f2f50328ca00a7f76b5fb625f4ef4ec 100644 --- a/spec.json +++ b/spec.json @@ -17,6 +17,10 @@ } ], "tags": [ + { + "name": "Item", + "description": "Endpoints for managing store and user inventory." + }, { "name": "Friend", "description": "API for managing friend relationships" @@ -345,6 +349,47 @@ "security": [] } }, + "/api/item/{itemId}": { + "post": { + "tags": [ + "Item" + ], + "summary": "Purchase an item", + "description": "Performs a purchase of the item by the user. Points will be deducted from the user.", + "operationId": "buyItem", + "parameters": [ + { + "name": "itemId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "403": { + "description": "Insufficient points to purchase the item", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + }, + "201": { + "description": "Item purchased and added to inventory successfully", + "content": { + "application/json": { + + } + } + } + } + } + }, "/api/images": { "post": { "tags": [ @@ -386,11 +431,36 @@ } } }, - "/api/goal/createGoal": { + "/api/goals": { + "get": { + "tags": [ + "Goal" + ], + "summary": "Get goals", + "description": "Get the goals of the authenticated user", + "operationId": "getGoals", + "responses": { + "200": { + "description": "Successfully retrieved the goals", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GoalDTO" + } + } + } + } + } + } + }, "post": { "tags": [ - "goal" + "Goal" ], + "summary": "Create a goal", + "description": "Create a new goal", "operationId": "createGoal", "requestBody": { "content": { @@ -403,10 +473,10 @@ "required": true }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Successfully created a goal", "content": { - "*/*": { + "application/json": { "schema": { "$ref": "#/components/schemas/GoalDTO" } @@ -416,6 +486,66 @@ } } }, + "/api/goals/update-challenge": { + "post": { + "tags": [ + "Goal" + ], + "summary": "Update a challenge", + "description": "Update a challenge day as completed", + "operationId": "updateChallenge", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MarkChallengeDTO" + } + } + }, + "required": true + }, + "responses": { + "401": { + "description": "Day is already completed or day outside of range", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ExceptionResponse" + } + } + } + }, + "200": { + "description": "Successfully updated the challenge" + } + } + } + }, + "/api/goals/update-challenge-amount": { + "post": { + "tags": [ + "Goal" + ], + "summary": "Update challenge saving amount", + "description": "Update the challenge saving amount", + "operationId": "updateChallengeAmount", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MarkChallengeDTO" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successfully updated the challenge" + } + } + } + }, "/api/friends/{userId}": { "post": { "tags": [ @@ -599,22 +729,22 @@ } ], "responses": { - "200": { - "description": "Email is valid", + "409": { + "description": "Email already exists", "content": { "*/*": { "schema": { - "type": "object" + "$ref": "#/components/schemas/ExceptionResponse" } } } }, - "409": { - "description": "Email already exists", + "200": { + "description": "Email is valid", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/ExceptionResponse" + "type": "object" } } } @@ -642,22 +772,22 @@ "required": true }, "responses": { - "201": { - "description": "Successfully signed up", + "409": { + "description": "Email already exists", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AuthenticationResponse" + "$ref": "#/components/schemas/ExceptionResponse" } } } }, - "409": { - "description": "Email already exists", + "201": { + "description": "Successfully signed up", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ExceptionResponse" + "$ref": "#/components/schemas/AuthenticationResponse" } } } @@ -695,8 +825,8 @@ } } }, - "404": { - "description": "User not found", + "401": { + "description": "Invalid credentials", "content": { "application/json": { "schema": { @@ -705,8 +835,8 @@ } } }, - "401": { - "description": "Invalid credentials", + "404": { + "description": "User not found", "content": { "application/json": { "schema": { @@ -1176,66 +1306,48 @@ } } }, - "/api/images/{id}": { + "/api/item/store": { "get": { "tags": [ - "Image" - ], - "summary": "Retrieve an image", - "description": "Retrieve an image from the server", - "operationId": "getImage", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - } + "Item" ], + "summary": "Get available store items", + "description": "Retrieves all items available in the store and a flag indicating whether the user has purchased each item.", + "operationId": "getStore", "responses": { - "404": { - "description": "Image not found", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - } - } - } - }, "200": { - "description": "Successfully retrieved the image", + "description": "List of store items fetched successfully", "content": { "*/*": { "schema": { - "type": "string", - "format": "binary" + "type": "array", + "items": { + "$ref": "#/components/schemas/ItemDTO" + } } } } } - }, - "security": [] + } } }, - "/api/goal/getGoals": { + "/api/item/inventory": { "get": { "tags": [ - "goal" + "Item" ], - "operationId": "getGoals", + "summary": "Get user inventory items", + "description": "Retrieves a list of all items currently in the inventory of the user.", + "operationId": "getInventory", "responses": { "200": { - "description": "OK", + "description": "List of inventory items fetched successfully", "content": { "*/*": { "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/GoalDTO" + "$ref": "#/components/schemas/InventoryDTO" } } } @@ -1244,24 +1356,49 @@ } } }, - "/api/goal/getGoal": { + "/api/images/{id}": { "get": { "tags": [ - "goal" + "Image" + ], + "summary": "Retrieve an image", + "description": "Retrieve an image from the server", + "operationId": "getImage", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } ], - "operationId": "getGoal", "responses": { "200": { - "description": "OK", + "description": "Successfully retrieved the image", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/GoalDTO" + "type": "string", + "format": "binary" + } + } + } + }, + "404": { + "description": "Image not found", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ExceptionResponse" } } } } - } + }, + "security": [] } }, "/api/friends": { @@ -1673,19 +1810,17 @@ "CreateGoalDTO": { "type": "object", "properties": { - "goalName": { + "name": { "type": "string" }, "description": { "type": "string" }, "targetAmount": { - "type": "integer", - "format": "int32" + "type": "number" }, "targetDate": { - "type": "string", - "format": "date-time" + "type": "string" } } }, @@ -1696,44 +1831,73 @@ "type": "integer", "format": "int64" }, - "potentialSavingAmount": { + "amount": { + "type": "number" + }, + "points": { "type": "integer", "format": "int32" }, - "points": { + "checkDays": { "type": "integer", "format": "int32" }, - "days": { + "totalDays": { "type": "integer", "format": "int32" }, - "createdAt": { + "startDate": { "type": "string", "format": "date-time" }, - "dailyChallengeProgressList": { + "endDate": { + "type": "string", + "format": "date-time" + }, + "challengeTemplate": { + "$ref": "#/components/schemas/ChallengeTemplateDTO" + }, + "progressList": { "type": "array", "items": { - "$ref": "#/components/schemas/DailyChallengeProgressDTO" + "$ref": "#/components/schemas/ProgressDTO" } } } }, - "DailyChallengeProgressDTO": { + "ChallengeTemplateDTO": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, - "challengeDay": { - "type": "integer", - "format": "int32" + "text": { + "type": "string" }, - "completedAt": { + "amount": { + "type": "number" + }, + "type": { "type": "string", - "format": "date-time" + "enum": [ + "NO_COFFEE", + "NO_CAR", + "SHORTER_SHOWER", + "SPEND_LESS_ON_FOOD", + "BUY_USED_CLOTHES", + "LESS_SHOPPING", + "DROP_SUBSCRIPTION", + "SELL_SOMETHING", + "BUY_USED", + "EAT_PACKED_LUNCH", + "STOP_SHOPPING", + "ZERO_SPENDING", + "RENT_YOUR_STUFF", + "MEATLESS", + "SCREEN_TIME_LIMIT", + "UNPLUGGED_ENTERTAINMENT" + ] } } }, @@ -1744,24 +1908,19 @@ "type": "integer", "format": "int64" }, - "goalName": { + "name": { "type": "string" }, "description": { "type": "string" }, "targetAmount": { - "type": "integer", - "format": "int32" + "type": "number" }, "targetDate": { "type": "string", "format": "date-time" }, - "completedAt": { - "type": "string", - "format": "date-time" - }, "createdAt": { "type": "string", "format": "date-time" @@ -1772,37 +1931,88 @@ "$ref": "#/components/schemas/ChallengeDTO" } }, - "participants": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ParticipantDTO" - } + "user": { + "$ref": "#/components/schemas/UserDTO" } } }, - "ParticipantDTO": { + "ProgressDTO": { "type": "object", "properties": { - "role": { - "type": "string", - "enum": [ - "CREATOR", - "CONTRIBUTOR" - ] + "id": { + "type": "integer", + "format": "int64" }, - "user": { - "$ref": "#/components/schemas/ParticipantUserDTO" + "day": { + "type": "integer", + "format": "int32" + }, + "amount": { + "type": "number" + }, + "completedAt": { + "type": "string", + "format": "date-time" } } }, - "ParticipantUserDTO": { + "UserDTO": { "type": "object", "properties": { + "id": { + "type": "integer", + "format": "int64" + }, "firstName": { "type": "string" }, "lastName": { "type": "string" + }, + "profileImage": { + "type": "integer", + "format": "int64" + }, + "email": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "role": { + "type": "string" + }, + "subscriptionLevel": { + "type": "string" + } + } + }, + "MarkChallengeDTO": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "day": { + "type": "integer", + "format": "int32" + }, + "amount": { + "type": "number" + } + } + }, + "ExceptionResponse": { + "type": "object", + "properties": { + "status": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" } } }, @@ -1835,18 +2045,6 @@ } } }, - "ExceptionResponse": { - "type": "object", - "properties": { - "status": { - "type": "integer", - "format": "int32" - }, - "message": { - "type": "string" - } - } - }, "ConfigurationDTO": { "type": "object", "properties": { @@ -1947,38 +2145,6 @@ } } }, - "UserDTO": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "format": "int64" - }, - "firstName": { - "type": "string" - }, - "lastName": { - "type": "string" - }, - "profileImage": { - "type": "integer", - "format": "int64" - }, - "email": { - "type": "string" - }, - "createdAt": { - "type": "string", - "format": "date-time" - }, - "role": { - "type": "string" - }, - "subscriptionLevel": { - "type": "string" - } - } - }, "BankAccountDTO": { "type": "object", "properties": { @@ -2076,6 +2242,49 @@ } } }, + "ItemDTO": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "itemName": { + "type": "string" + }, + "price": { + "type": "integer", + "format": "int32" + }, + "imageId": { + "type": "integer", + "format": "int64" + }, + "alreadyBought": { + "type": "boolean" + } + } + }, + "InventoryDTO": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "itemName": { + "type": "string" + }, + "imageId": { + "type": "integer", + "format": "int64" + }, + "boughtAt": { + "type": "string", + "format": "date-time" + } + } + }, "BudgetResponseDTO": { "type": "object", "properties": { diff --git a/src/api/index.ts b/src/api/index.ts index 0a46cc0e4ddd97a94230ae6cffde43965f222b93..c6e6069aeab9c54ebbc0f93c7beb88b43b0e35de 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -18,23 +18,25 @@ export type { BankProfileResponseDTO } from './models/BankProfileResponseDTO'; export type { BudgetRequestDTO } from './models/BudgetRequestDTO'; export type { BudgetResponseDTO } from './models/BudgetResponseDTO'; export type { ChallengeDTO } from './models/ChallengeDTO'; +export { ChallengeTemplateDTO } from './models/ChallengeTemplateDTO'; export type { ConfigurationDTO } from './models/ConfigurationDTO'; export type { CreateGoalDTO } from './models/CreateGoalDTO'; -export type { DailyChallengeProgressDTO } from './models/DailyChallengeProgressDTO'; export type { ExceptionResponse } from './models/ExceptionResponse'; export type { ExpenseRequestDTO } from './models/ExpenseRequestDTO'; export type { ExpenseResponseDTO } from './models/ExpenseResponseDTO'; export type { FeedbackRequestDTO } from './models/FeedbackRequestDTO'; export type { FeedbackResponseDTO } from './models/FeedbackResponseDTO'; export type { GoalDTO } from './models/GoalDTO'; +export type { InventoryDTO } from './models/InventoryDTO'; +export type { ItemDTO } from './models/ItemDTO'; export type { LeaderboardDTO } from './models/LeaderboardDTO'; export type { LeaderboardEntryDTO } from './models/LeaderboardEntryDTO'; export type { LoginRequest } from './models/LoginRequest'; -export { ParticipantDTO } from './models/ParticipantDTO'; -export type { ParticipantUserDTO } from './models/ParticipantUserDTO'; +export type { MarkChallengeDTO } from './models/MarkChallengeDTO'; export type { PasswordResetDTO } from './models/PasswordResetDTO'; export type { PasswordUpdateDTO } from './models/PasswordUpdateDTO'; export type { ProfileDTO } from './models/ProfileDTO'; +export type { ProgressDTO } from './models/ProgressDTO'; export type { SignUpRequest } from './models/SignUpRequest'; export type { TransactionDTO } from './models/TransactionDTO'; export type { UserDTO } from './models/UserDTO'; @@ -46,6 +48,7 @@ export { BankProfileControllerService } from './services/BankProfileControllerSe export { FriendService } from './services/FriendService'; export { GoalService } from './services/GoalService'; export { ImageService } from './services/ImageService'; +export { ItemService } from './services/ItemService'; export { LeaderboardService } from './services/LeaderboardService'; export { TransactionControllerService } from './services/TransactionControllerService'; export { UserService } from './services/UserService'; diff --git a/src/api/models/ChallengeDTO.ts b/src/api/models/ChallengeDTO.ts index f5bd38d483c363d921274e9ed77dbd5e6d4aef75..3ccf0f055c0ffb92c2f2612a02aaf5e25d3c856b 100644 --- a/src/api/models/ChallengeDTO.ts +++ b/src/api/models/ChallengeDTO.ts @@ -2,13 +2,17 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { DailyChallengeProgressDTO } from './DailyChallengeProgressDTO'; +import type { ChallengeTemplateDTO } from './ChallengeTemplateDTO'; +import type { ProgressDTO } from './ProgressDTO'; export type ChallengeDTO = { id?: number; - potentialSavingAmount?: number; + amount?: number; points?: number; - days?: number; - createdAt?: string; - dailyChallengeProgressList?: Array<DailyChallengeProgressDTO>; + checkDays?: number; + totalDays?: number; + startDate?: string; + endDate?: string; + challengeTemplate?: ChallengeTemplateDTO; + progressList?: Array<ProgressDTO>; }; diff --git a/src/api/models/ChallengeTemplateDTO.ts b/src/api/models/ChallengeTemplateDTO.ts new file mode 100644 index 0000000000000000000000000000000000000000..323e64de48b8a201d3c4da78e5de83a904b0b0b1 --- /dev/null +++ b/src/api/models/ChallengeTemplateDTO.ts @@ -0,0 +1,31 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type ChallengeTemplateDTO = { + id?: number; + text?: string; + amount?: number; + type?: ChallengeTemplateDTO.type; +}; +export namespace ChallengeTemplateDTO { + export enum type { + NO_COFFEE = 'NO_COFFEE', + NO_CAR = 'NO_CAR', + SHORTER_SHOWER = 'SHORTER_SHOWER', + SPEND_LESS_ON_FOOD = 'SPEND_LESS_ON_FOOD', + BUY_USED_CLOTHES = 'BUY_USED_CLOTHES', + LESS_SHOPPING = 'LESS_SHOPPING', + DROP_SUBSCRIPTION = 'DROP_SUBSCRIPTION', + SELL_SOMETHING = 'SELL_SOMETHING', + BUY_USED = 'BUY_USED', + EAT_PACKED_LUNCH = 'EAT_PACKED_LUNCH', + STOP_SHOPPING = 'STOP_SHOPPING', + ZERO_SPENDING = 'ZERO_SPENDING', + RENT_YOUR_STUFF = 'RENT_YOUR_STUFF', + MEATLESS = 'MEATLESS', + SCREEN_TIME_LIMIT = 'SCREEN_TIME_LIMIT', + UNPLUGGED_ENTERTAINMENT = 'UNPLUGGED_ENTERTAINMENT', + } +} + diff --git a/src/api/models/CreateGoalDTO.ts b/src/api/models/CreateGoalDTO.ts index 61eb0457b42b2aebf8be3c560bcd62d2346648e4..2e6e535f0b0a2317ef26e76c8db8f53572cbcd8d 100644 --- a/src/api/models/CreateGoalDTO.ts +++ b/src/api/models/CreateGoalDTO.ts @@ -3,7 +3,7 @@ /* tslint:disable */ /* eslint-disable */ export type CreateGoalDTO = { - goalName?: string; + name?: string; description?: string; targetAmount?: number; targetDate?: string; diff --git a/src/api/models/GoalDTO.ts b/src/api/models/GoalDTO.ts index 004eb49fd0bec010a1d4227bac6ec6bbc3daea50..c24e9abfb1d37acc49db64803d4da80a901960ce 100644 --- a/src/api/models/GoalDTO.ts +++ b/src/api/models/GoalDTO.ts @@ -3,16 +3,15 @@ /* tslint:disable */ /* eslint-disable */ import type { ChallengeDTO } from './ChallengeDTO'; -import type { ParticipantDTO } from './ParticipantDTO'; +import type { UserDTO } from './UserDTO'; export type GoalDTO = { id?: number; - goalName?: string; + name?: string; description?: string; targetAmount?: number; targetDate?: string; - completedAt?: string; createdAt?: string; challenges?: Array<ChallengeDTO>; - participants?: Array<ParticipantDTO>; + user?: UserDTO; }; diff --git a/src/api/models/InventoryDTO.ts b/src/api/models/InventoryDTO.ts new file mode 100644 index 0000000000000000000000000000000000000000..826a6b61da10137a07982263be585d3be2571bfa --- /dev/null +++ b/src/api/models/InventoryDTO.ts @@ -0,0 +1,11 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type InventoryDTO = { + id?: number; + itemName?: string; + imageId?: number; + boughtAt?: string; +}; + diff --git a/src/api/models/ItemDTO.ts b/src/api/models/ItemDTO.ts new file mode 100644 index 0000000000000000000000000000000000000000..b2c65c3135bb7307dd11c25a5c4defe7781af209 --- /dev/null +++ b/src/api/models/ItemDTO.ts @@ -0,0 +1,12 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type ItemDTO = { + id?: number; + itemName?: string; + price?: number; + imageId?: number; + alreadyBought?: boolean; +}; + diff --git a/src/api/models/ParticipantUserDTO.ts b/src/api/models/MarkChallengeDTO.ts similarity index 60% rename from src/api/models/ParticipantUserDTO.ts rename to src/api/models/MarkChallengeDTO.ts index 5499c09f765c2b01e58efea75581a8f14d3f9e40..09c06b8a91f40448ceb2fe25867da13de7f713cb 100644 --- a/src/api/models/ParticipantUserDTO.ts +++ b/src/api/models/MarkChallengeDTO.ts @@ -2,8 +2,9 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -export type ParticipantUserDTO = { - firstName?: string; - lastName?: string; +export type MarkChallengeDTO = { + id?: number; + day?: number; + amount?: number; }; diff --git a/src/api/models/ParticipantDTO.ts b/src/api/models/ParticipantDTO.ts deleted file mode 100644 index 0615b50834924e46416818dffbb00718b3607bab..0000000000000000000000000000000000000000 --- a/src/api/models/ParticipantDTO.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* generated using openapi-typescript-codegen -- do not edit */ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -import type { ParticipantUserDTO } from './ParticipantUserDTO'; -export type ParticipantDTO = { - role?: ParticipantDTO.role; - user?: ParticipantUserDTO; -}; -export namespace ParticipantDTO { - export enum role { - CREATOR = 'CREATOR', - CONTRIBUTOR = 'CONTRIBUTOR', - } -} - diff --git a/src/api/models/DailyChallengeProgressDTO.ts b/src/api/models/ProgressDTO.ts similarity index 72% rename from src/api/models/DailyChallengeProgressDTO.ts rename to src/api/models/ProgressDTO.ts index c7bda736cefef3aebff0533272807cde205e16ee..cb6f11746458912e9efef6438bb3278ff585c2d6 100644 --- a/src/api/models/DailyChallengeProgressDTO.ts +++ b/src/api/models/ProgressDTO.ts @@ -2,9 +2,10 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -export type DailyChallengeProgressDTO = { +export type ProgressDTO = { id?: number; - challengeDay?: number; + day?: number; + amount?: number; completedAt?: string; }; diff --git a/src/api/services/GoalService.ts b/src/api/services/GoalService.ts index 28ae857fcaf1e5268dc6aefc5ba9c9e0d27398f2..0f0781e3492860efcf75ae71afa3d23fec0685f1 100644 --- a/src/api/services/GoalService.ts +++ b/src/api/services/GoalService.ts @@ -4,12 +4,27 @@ /* eslint-disable */ import type { CreateGoalDTO } from '../models/CreateGoalDTO'; import type { GoalDTO } from '../models/GoalDTO'; +import type { MarkChallengeDTO } from '../models/MarkChallengeDTO'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; export class GoalService { /** - * @returns GoalDTO OK + * Get goals + * Get the goals of the authenticated user + * @returns GoalDTO Successfully retrieved the goals + * @throws ApiError + */ + public static getGoals(): CancelablePromise<Array<GoalDTO>> { + return __request(OpenAPI, { + method: 'GET', + url: '/api/goals', + }); + } + /** + * Create a goal + * Create a new goal + * @returns GoalDTO Successfully created a goal * @throws ApiError */ public static createGoal({ @@ -19,29 +34,48 @@ export class GoalService { }): CancelablePromise<GoalDTO> { return __request(OpenAPI, { method: 'POST', - url: '/api/goal/createGoal', + url: '/api/goals', body: requestBody, mediaType: 'application/json', }); } /** - * @returns GoalDTO OK + * Update a challenge + * Update a challenge day as completed + * @returns any Successfully updated the challenge * @throws ApiError */ - public static getGoals(): CancelablePromise<Array<GoalDTO>> { + public static updateChallenge({ + requestBody, + }: { + requestBody: MarkChallengeDTO, + }): CancelablePromise<any> { return __request(OpenAPI, { - method: 'GET', - url: '/api/goal/getGoals', + method: 'POST', + url: '/api/goals/update-challenge', + body: requestBody, + mediaType: 'application/json', + errors: { + 401: `Day is already completed or day outside of range`, + }, }); } /** - * @returns GoalDTO OK + * Update challenge saving amount + * Update the challenge saving amount + * @returns any Successfully updated the challenge * @throws ApiError */ - public static getGoal(): CancelablePromise<GoalDTO> { + public static updateChallengeAmount({ + requestBody, + }: { + requestBody: MarkChallengeDTO, + }): CancelablePromise<any> { return __request(OpenAPI, { - method: 'GET', - url: '/api/goal/getGoal', + method: 'POST', + url: '/api/goals/update-challenge-amount', + body: requestBody, + mediaType: 'application/json', }); } } diff --git a/src/api/services/ItemService.ts b/src/api/services/ItemService.ts new file mode 100644 index 0000000000000000000000000000000000000000..ae2a3a8997ee79ac0fd22e289c153666a79b7396 --- /dev/null +++ b/src/api/services/ItemService.ts @@ -0,0 +1,57 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { InventoryDTO } from '../models/InventoryDTO'; +import type { ItemDTO } from '../models/ItemDTO'; +import type { CancelablePromise } from '../core/CancelablePromise'; +import { OpenAPI } from '../core/OpenAPI'; +import { request as __request } from '../core/request'; +export class ItemService { + /** + * Purchase an item + * Performs a purchase of the item by the user. Points will be deducted from the user. + * @returns any Item purchased and added to inventory successfully + * @throws ApiError + */ + public static buyItem({ + itemId, + }: { + itemId: number, + }): CancelablePromise<any> { + return __request(OpenAPI, { + method: 'POST', + url: '/api/item/{itemId}', + path: { + 'itemId': itemId, + }, + errors: { + 403: `Insufficient points to purchase the item`, + }, + }); + } + /** + * Get available store items + * Retrieves all items available in the store and a flag indicating whether the user has purchased each item. + * @returns ItemDTO List of store items fetched successfully + * @throws ApiError + */ + public static getStore(): CancelablePromise<Array<ItemDTO>> { + return __request(OpenAPI, { + method: 'GET', + url: '/api/item/store', + }); + } + /** + * Get user inventory items + * Retrieves a list of all items currently in the inventory of the user. + * @returns InventoryDTO List of inventory items fetched successfully + * @throws ApiError + */ + public static getInventory(): CancelablePromise<Array<InventoryDTO>> { + return __request(OpenAPI, { + method: 'GET', + url: '/api/item/inventory', + }); + } +} diff --git a/src/components/UserProfile/UserProfileLayout.vue b/src/components/UserProfile/UserProfileLayout.vue index 46dbca809716795ae2b958428ec52e4005718b81..f2fc2eb4aa70aea14084e2dde1ecc33aaa2d74c3 100644 --- a/src/components/UserProfile/UserProfileLayout.vue +++ b/src/components/UserProfile/UserProfileLayout.vue @@ -3,16 +3,17 @@ import { ref, onMounted } from "vue"; import { useRouter } from "vue-router"; import { useUserInfoStore } from "../../stores/UserStore"; import { UserService } from "@/api"; +import { ItemService } from "@/api"; let numberOfHistory = 6; - let cardTitles = ["Spain tour", "Food waste", "Coffee", "Concert", "New book", "Pretty clothes"] - let firstname = ref(); let lastname = ref(); const imageUrl = ref(`../src/assets/userprofile.png`); const router = useRouter(); +const inventory = ref([] as any); +const backgroundName = ref(""); async function setupForm() { try { @@ -22,11 +23,28 @@ async function setupForm() { firstname.value = response.firstName; lastname.value = response.lastName; imageUrl.value = "http://localhost:8080/api/images/" + response.profileImage; + getInventory(); } catch (err) { console.error(err) } } +const getInventory = async () => { + try { + const response = await ItemService.getInventory(); + inventory.value = response; + } catch (error) { + console.log(error); + } +} + +const selectItem = (item: any) => { + backgroundName.value = item.itemName; + useUserInfoStore().setUserInfo({ + roadBackground: item.imageId, + }) +} + onMounted(() => { setupForm() }) @@ -48,8 +66,8 @@ const toUpdateUserSettings = () => { <div class="card"> <div class="rounded-top text-white d-flex flex-row bg-primary" style="height:200px;"> <div class="ms-4 mt-5 d-flex flex-column" style="width: 150px;"> - <img :src="imageUrl" alt="Generisk plassholderbilde" - class="img-fluid img-thumbnail mt-4 mb-2" style="width: 150px; z-index: 1"> + <img :src="imageUrl" alt="Generisk plassholderbilde" class="img-fluid img-thumbnail mt-4 mb-2" + style="width: 150px; z-index: 1"> <button type="button" data-mdb-button-init data-mdb-ripple-init class="btn btn-outline-primary" data-mdb-ripple-color="dark" style="z-index: 1;" id="toUpdate" @click="toUpdateUserSettings"> Rediger profil @@ -71,6 +89,26 @@ const toUpdateUserSettings = () => { </div> </div> </div> + <div class="card-body p-1 text-black"> + <div class="row"> + <div class="col"> + <div class="container-fluid"> + <h1 class="mt-5 text-start badges-text">Lageret ditt</h1> + <div class="scrolling-wrapper-badges row flex-row flex-nowrap mt-4 pb-4 pt-2"> + <div v-for="product in inventory" :key="product.id" class="card text-center" + style="width: 12rem; border: none; cursor: pointer; margin: 1rem; border: 2px solid black" @click="selectItem(product)"> + <img :src="`http://localhost:8080/api/images/${product.imageId}`" class="card-img-top" + alt="..." /> + <div class="card-body"> + <h5 class="card-title">{{ product.itemName }}</h5> + </div> + </div> + </div> + <div v-if="backgroundName" class="text-success">You selected the background: <strong>{{ backgroundName }}!</strong></div> + </div> + </div> + </div> + </div> <div class="card-body p-1 text-black"> <div class="row"> <div class="col"> @@ -131,7 +169,8 @@ const toUpdateUserSettings = () => { <div class="card-body"> <h5 class="card-title">{{ cardTitles[index - 1] }}</h5> <p class="card-text">Penger spart: 200 <br />Du har fullført en utfordring: 21</p> - <p class="card-text"><small class="text-muted">Sist oppdatert for 3 minutter siden</small></p> + <p class="card-text"><small class="text-muted">Sist oppdatert for 3 minutter + siden</small></p> <a href="#" class="btn stretched-link" @click="toRoadmap"></a> </div> </div> diff --git a/src/stores/UserStore.ts b/src/stores/UserStore.ts index 9c852dbcca932782cdcab4ace9c6816b7f762cf7..a3fd5a3d7f772fd3133e3e7b1f98332708a44ee9 100644 --- a/src/stores/UserStore.ts +++ b/src/stores/UserStore.ts @@ -37,6 +37,7 @@ export type UserStoreInfo = { accessToken?: string; role?: string; subscriptionLevel?: string; + roadBackground?: number; profileImage?: number; }; @@ -50,6 +51,7 @@ export const useUserInfoStore = defineStore('UserInfoStore', { accessToken: '', role: '', subscriptionLevel: '', + roadBackground: 0, profileImage: 0, }), persist: { @@ -71,6 +73,7 @@ export const useUserInfoStore = defineStore('UserInfoStore', { userinfo.accessToken && (OpenAPI.TOKEN = this.$state.accessToken); userinfo.role && (this.$state.role = userinfo.role); userinfo.subscriptionLevel && (this.$state.subscriptionLevel = userinfo.subscriptionLevel); + userinfo.roadBackground && (this.$state.roadBackground = userinfo.roadBackground); userinfo.profileImage && (this.$state.profileImage = userinfo.profileImage); }, clearUserInfo() { @@ -81,6 +84,7 @@ export const useUserInfoStore = defineStore('UserInfoStore', { this.$state.accessToken = ''; this.$state.role = ''; this.$state.subscriptionLevel = ''; + this.$state.roadBackground = 0; this.$state.profileImage = 0; OpenAPI.TOKEN = undefined; }, diff --git a/src/views/ShopView.vue b/src/views/ShopView.vue index aa5f96794223a640bc94feb04fdf90b2aeba1e46..f89b948c9954468514615b5d3cce8d840cfab31d 100644 --- a/src/views/ShopView.vue +++ b/src/views/ShopView.vue @@ -12,7 +12,8 @@ <img src="@/assets/items/adfree.png" class="card-img-top" alt="..."> <div class="card-body"> <h5 class="card-title">Adfree</h5> - <button type="button" class="btn btn-primary" id="buttonStyle" @click="buyNoAds"> +35kr</button> + <button type="button" class="btn btn-primary" id="buttonStyle" @click="buyNoAds"> + +35kr</button> </div> </div> <div class="card text-center" style="width: 16rem; border: none"> @@ -26,38 +27,19 @@ </div> </div> <div class="col-md-12"> - <h1>Fantacy</h1> + <h1>Items</h1> <div class="category row justify-content-between mb-5 m-2"> - <!--<div class="col-md-4" v-for="product in products" :key="product.id">--> - <div class="card text-center" style="width: 16rem; border: none"> - <img src="@/assets/items/galaxy.jpg" class="card-img-top" alt="..."> - <div class="card-body"> - <h5 class="card-title">The panda</h5> - <ShopButton button-text="100"></ShopButton> - </div> - </div> - <div class="card text-center" style="width: 16rem; border: none"> - <img src="@/assets/items/galaxy.jpg" class="card-img-top" alt="..."> - <div class="card-body"> - <h5 class="card-title">The panda</h5> - <ShopButton button-text="100"></ShopButton> - </div> - </div> - <div class="card text-center" style="width: 16rem; border: none"> - <img src="@/assets/items/galaxy.jpg" class="card-img-top" alt="..."> + <div v-for="product in products" :key="product.id" class="card text-center" + style="width: 16rem; border: none"> + <img :src="`http://localhost:8080/api/images/${product.imageId}`" class="card-img-top" + alt="..." /> <div class="card-body"> - <h5 class="card-title">The panda</h5> - <ShopButton button-text="100"></ShopButton> + <h5 class="card-title">{{ product.itemName }}</h5> + <ShopButton v-if="!product.alreadyBought" :button-text="product.price" + @click="buyItem(product.id)"></ShopButton> + <p v-else>Owned</p> </div> </div> - <div class="card text-center" style="width: 16rem; border: none"> - <img src="@/assets/items/galaxy.jpg" class="card-img-top" alt="..."> - <div class="card-body"> - <h5 class="card-title">The panda</h5> - <ShopButton button-text="100"></ShopButton> - </div> - </div> - <!--</div>--> </div> </div> <div class="col-md-12"> @@ -93,9 +75,29 @@ <script setup lang="ts"> import ShopButton from '@/components/Buttons/ShopButton.vue'; -import { ref } from 'vue'; +import { ref, onMounted } from 'vue'; import { UserService } from '@/api'; import { useUserInfoStore } from '@/stores/UserStore'; +import { ItemService } from '@/api'; + +const products = ref([] as any); + +const getStore = async () => { + const response = await ItemService.getStore(); + products.value = response; + console.log(response); +} + +const buyItem = async (itemId: number) => { + try { + const response = await ItemService.buyItem({ itemId: itemId }); + console.log(response); + const responseStore = await ItemService.getStore(); + products.value = responseStore; + } catch (error) { + console.log(error); + } +} const buyPremium = async () => { try { @@ -118,6 +120,10 @@ const buyNoAds = async () => { console.log(error); } } + +onMounted(() => { + getStore(); +}) </script> <style scoped>