From afe1682bf45bde76947ab96d2634444ac1a1383e Mon Sep 17 00:00:00 2001 From: bush1D3v Date: Sat, 9 Nov 2024 17:44:20 -0300 Subject: [PATCH] bomb commit --- api/src/proxy/BrapiDev.ts | 51 +++++++++------- api/src/proxy/CoinMarketCap.ts | 74 +++++++++++++----------- api/src/proxy/Finnhub.ts | 66 ++++++++++++++++----- api/src/routes/Finnhub.ts | 3 +- api/src/types/BrapiDev/SortBy.ts | 1 + api/src/types/BrapiDev/SortOrder.ts | 1 + api/src/types/CoinMarketCap/Sort.ts | 1 + app/components/CurrencyQuotes/Dialog.vue | 58 +++++++++---------- app/components/HomeTable.vue | 31 ++++++++++ app/events/brapiDevEventEmitter.ts | 30 +++++----- app/events/coinMarketCapEventEmitter.ts | 30 +++++----- app/events/finnhubEventEmitter.ts | 30 +++++----- app/services/BrapiDev.ts | 39 ++++++++----- app/services/CoinMarketCap.ts | 60 +++++++++++-------- app/services/Finnhub.ts | 62 +++++++++++++++----- app/stores/useCryptoCurrencyStore.ts | 61 ++++++++++--------- app/stores/useCurrencyQuotesStore.ts | 50 ++++++++-------- app/stores/useNewsStore.ts | 37 ++++++------ app/stores/useStocksCurrencyStore.ts | 49 +++++++++------- app/types/BrapiDev/SortBy.ts | 1 + app/types/BrapiDev/SortOrder.ts | 1 + app/types/CoinMarketCap/Sort.ts | 1 + app/types/Finnhub/Category.ts | 2 +- app/utils/formatDate.ts | 12 ++++ app/views/Home.vue | 22 ++++++- 25 files changed, 488 insertions(+), 285 deletions(-) create mode 100644 api/src/types/BrapiDev/SortBy.ts create mode 100644 api/src/types/BrapiDev/SortOrder.ts create mode 100644 api/src/types/CoinMarketCap/Sort.ts create mode 100644 app/components/HomeTable.vue create mode 100644 app/types/BrapiDev/SortBy.ts create mode 100644 app/types/BrapiDev/SortOrder.ts create mode 100644 app/types/CoinMarketCap/Sort.ts create mode 100644 app/utils/formatDate.ts diff --git a/api/src/proxy/BrapiDev.ts b/api/src/proxy/BrapiDev.ts index ee75e8e..bdf2d25 100644 --- a/api/src/proxy/BrapiDev.ts +++ b/api/src/proxy/BrapiDev.ts @@ -1,25 +1,29 @@ -import type {Request, Response} from "express"; -import {get} from "../helpers/HttpClient.ts"; +import type { Request, Response } from "express"; +import { get } from "../helpers/HttpClient.ts"; import dotenv from "dotenv"; -import type {Stock} from "../types/BrapiDev/Stock.ts"; +import type { Stock } from "../types/BrapiDev/Stock.ts"; +import type { SortBy } from "../types/BrapiDev/SortBy.ts"; +import type { SortOrder } from "../types/BrapiDev/SortOrder.ts"; dotenv.config(); const BASE_API_URL = process.env.BRAPI_HOST as string; const API_KEY = process.env.BRAPI_KEY as string; const defaultHeaders = { - "Accept-Encoding": "deflate, gzip", - "referrer-policy": "origin-when-cross-origin", - "X-Api-Key": API_KEY, + "Accept-Encoding": "deflate, gzip", + "referrer-policy": "origin-when-cross-origin", + "X-Api-Key": API_KEY, }; interface QueryParams { - limit?: number; - page?: number; + limit?: number; + page?: number; + sortBy?: SortBy; + sortOrder?: SortOrder; } interface ResponseListStocks { - stocks: Stock[]; + stocks: Stock[]; } /** @@ -31,19 +35,26 @@ interface ResponseListStocks { * @throws {Error} If the request to the external API fails */ export async function listStocks(req: Request, res: Response): Promise { - const {limit = 12, page = 1}: QueryParams = req.query; - const url = `${BASE_API_URL}/api/quote/list?limit=${limit}&page=${page}`; + const { limit = 12, page = 1, sortBy, sortOrder }: QueryParams = req.query; - try { - const response = await get(url, defaultHeaders); + let url: string; - if (!response.ok) throw new Error(await response.json()); + if (sortBy && sortOrder) { + url = `${BASE_API_URL}/api/quote/list?limit=${limit}&page=${page}&sortBy=${sortBy}&sortOrder=${sortOrder}`; + } else { + url = `${BASE_API_URL}/api/quote/list?limit=${limit}&page=${page}`; + } - const jsonData: ResponseListStocks = await response.json(); + try { + const response = await get(url, defaultHeaders); - res.status(200).json(jsonData.stocks); - } catch (error) { - console.error(error); - res.status(500).json({error: error}); - } + if (!response.ok) throw new Error(await response.json()); + + const jsonData: ResponseListStocks = await response.json(); + + res.status(200).json(jsonData.stocks); + } catch (error) { + console.error(error); + res.status(500).json({ error: error }); + } } diff --git a/api/src/proxy/CoinMarketCap.ts b/api/src/proxy/CoinMarketCap.ts index 2ff07a5..c2315d1 100644 --- a/api/src/proxy/CoinMarketCap.ts +++ b/api/src/proxy/CoinMarketCap.ts @@ -1,25 +1,27 @@ -import type {Request, Response} from "express"; -import {get} from "../helpers/HttpClient.ts"; +import type { Request, Response } from "express"; +import { get } from "../helpers/HttpClient.ts"; import dotenv from "dotenv"; -import type {CryptoCurrency} from "../types/CoinMarketCap/CryptoCurrency.ts"; +import type { CryptoCurrency } from "../types/CoinMarketCap/CryptoCurrency.ts"; +import type { Sort } from "../types/CoinMarketCap/Sort.ts"; dotenv.config(); const BASE_API_URL = process.env.COINMARKETCAP_HOST as string; const API_KEY = process.env.COINMARKETCAP_KEY as string; const defaultHeaders = { - "Accept-Encoding": "deflate, gzip", - "referrer-policy": "origin-when-cross-origin", - "X-CMC_PRO_API_KEY": API_KEY, + "Accept-Encoding": "deflate, gzip", + "referrer-policy": "origin-when-cross-origin", + "X-CMC_PRO_API_KEY": API_KEY, }; interface ListingsLatestQueryParams { - limit?: number; - start?: number; + limit?: number; + start?: number; + sort?: Sort; } interface ResponseListingLatestData { - data: CryptoCurrency[]; + data: CryptoCurrency[]; } /** @@ -31,29 +33,35 @@ interface ResponseListingLatestData { * @throws {Error} If the request to the external API fails */ export async function listingsLatest(req: Request, res: Response): Promise { - const {limit = 12, start = 1}: ListingsLatestQueryParams = req.query; - const url = `${BASE_API_URL}/v1/cryptocurrency/listings/latest?limit=${limit}&start=${start}`; + const { limit = 12, start = 1, sort }: ListingsLatestQueryParams = req.query; - try { - const response = await get(url, defaultHeaders); + let url: string; + if (sort) { + url = `${BASE_API_URL}/v1/cryptocurrency/listings/latest?limit=${limit}&start=${start}&sort=${sort}`; + } else { + url = `${BASE_API_URL}/v1/cryptocurrency/listings/latest?limit=${limit}&start=${start}`; + } - if (!response.ok) throw new Error(await response.json()); + try { + const response = await get(url, defaultHeaders); - const data: ResponseListingLatestData = await response.json(); + if (!response.ok) throw new Error(await response.json()); - res.json(data.data); - } catch (error) { - console.error(error); - res.status(500).json({error: error}); - } + const data: ResponseListingLatestData = await response.json(); + + res.json(data.data); + } catch (error) { + console.error(error); + res.status(500).json({ error: error }); + } } interface DetailQueryParams { - slug?: string; + slug?: string; } interface ResponseDetailData { - data: CryptoCurrency; + data: CryptoCurrency; } /** @@ -65,19 +73,19 @@ interface ResponseDetailData { * @throws {Error} If the request to the external API fails */ export async function detail(req: Request, res: Response): Promise { - const {slug}: DetailQueryParams = req.query; - const url = `${BASE_API_URL}/v2/cryptocurrency/info?slug=${slug}`; + const { slug }: DetailQueryParams = req.query; + const url = `${BASE_API_URL}/v2/cryptocurrency/info?slug=${slug}`; - try { - const response = await get(url, defaultHeaders); + try { + const response = await get(url, defaultHeaders); - if (!response.ok) throw new Error(await response.json()); + if (!response.ok) throw new Error(await response.json()); - const data: ResponseDetailData = await response.json(); + const data: ResponseDetailData = await response.json(); - res.json(data.data).status(200); - } catch (error) { - console.error(error); - res.status(500).json({error: error}); - } + res.json(data.data).status(200); + } catch (error) { + console.error(error); + res.status(500).json({ error: error }); + } } diff --git a/api/src/proxy/Finnhub.ts b/api/src/proxy/Finnhub.ts index 0252a33..49853d2 100644 --- a/api/src/proxy/Finnhub.ts +++ b/api/src/proxy/Finnhub.ts @@ -1,16 +1,20 @@ -import type {Request, Response} from "express"; -import {get} from "../helpers/HttpClient.ts"; +import type { Request, Response } from "express"; +import { get } from "../helpers/HttpClient.ts"; import dotenv from "dotenv"; -import type {New} from "../types/Finnhub/New.ts"; +import type { New } from "../types/Finnhub/New.ts"; dotenv.config(); const BASE_API_URL = process.env.FINNHUB_HOST as string; const API_KEY = process.env.FINNHUB_KEY as string; const defaultHeaders = { - "X-Finnhub-Token": API_KEY, + "X-Finnhub-Token": API_KEY, }; +interface ListingsMarketNewsQueryParams { + category?: string; +} + /** * @description Handles the request to get the list of market news. * @@ -20,19 +24,51 @@ const defaultHeaders = { * @throws {Error} If the request to the external API fails */ export async function listMarketNews(req: Request, res: Response): Promise { - const {category} = req.query; - const url = `${BASE_API_URL}/api/v1/news?category=${category}`; + const { category }: ListingsMarketNewsQueryParams = req.query; + const url = `${BASE_API_URL}/api/v1/news?category=${category}`; + + try { + const response = await get(url, defaultHeaders); + + if (!response.ok) throw new Error(await response.json()); + + const jsonData: New[] = await response.json(); + + res.json(jsonData); + } catch (error) { + console.error(error); + res.status(500).json({ error: error }); + } +} + +interface ListingsCompanyNewsQueryParams { + symbol?: string; + from?: string; + to?: string; +} + +/** + * @description Handles the request to get the list of company news. + * + * @param {Request} req - The request object + * @param {Response} res - The response object + * @returns {void} + * @throws {Error} If the request to the external API fails + */ +export async function listCompanyNews(req: Request, res: Response): Promise { + const { symbol, from, to }: ListingsCompanyNewsQueryParams = req.query; + const url = `${BASE_API_URL}/api/v1/company-news?symbol=${symbol}&from=${from}&to=${to}`; - try { - const response = await get(url, defaultHeaders); + try { + const response = await get(url, defaultHeaders); - if (!response.ok) throw new Error(await response.json()); + if (!response.ok) throw new Error(await response.json()); - const jsonData: New[] = await response.json(); + const jsonData: New[] = await response.json(); - res.json(jsonData); - } catch (error) { - console.error(error); - res.status(500).json({error: error}); - } + res.json(jsonData); + } catch (error) { + console.error(error); + res.status(500).json({ error: error }); + } } diff --git a/api/src/routes/Finnhub.ts b/api/src/routes/Finnhub.ts index 91b395a..1c56d68 100644 --- a/api/src/routes/Finnhub.ts +++ b/api/src/routes/Finnhub.ts @@ -1,8 +1,9 @@ import express from "express"; -import {listMarketNews} from "../proxy/Finnhub.ts"; +import { listCompanyNews, listMarketNews } from "../proxy/Finnhub.ts"; const finnhubRoutes = express(); finnhubRoutes.get("/api/v1/news", listMarketNews); +finnhubRoutes.get("/api/v1/company-news", listCompanyNews); export default finnhubRoutes; diff --git a/api/src/types/BrapiDev/SortBy.ts b/api/src/types/BrapiDev/SortBy.ts new file mode 100644 index 0000000..cd2bfae --- /dev/null +++ b/api/src/types/BrapiDev/SortBy.ts @@ -0,0 +1 @@ +export type SortBy = "name" | "close" | "change" | "change_abs" | "volume" | "market_cap_basic"; diff --git a/api/src/types/BrapiDev/SortOrder.ts b/api/src/types/BrapiDev/SortOrder.ts new file mode 100644 index 0000000..4b12a7d --- /dev/null +++ b/api/src/types/BrapiDev/SortOrder.ts @@ -0,0 +1 @@ +export type SortOrder = "asc" | "desc"; diff --git a/api/src/types/CoinMarketCap/Sort.ts b/api/src/types/CoinMarketCap/Sort.ts new file mode 100644 index 0000000..d564c91 --- /dev/null +++ b/api/src/types/CoinMarketCap/Sort.ts @@ -0,0 +1 @@ +export type Sort = "name" | "symbol" | "date_added" | "market_cap" | "market_cap_strict" | "price" | "circulating_supply" | "total_supply" | "max_supply" | "num_market_pairs" | "volume_24h" | "percent_change_1h" | "percent_change_24h" | "percent_change_7d" | "market_cap_by_total_supply_strict" | "volume_7d" | " volume_30d" diff --git a/app/components/CurrencyQuotes/Dialog.vue b/app/components/CurrencyQuotes/Dialog.vue index 58e896d..64f4646 100644 --- a/app/components/CurrencyQuotes/Dialog.vue +++ b/app/components/CurrencyQuotes/Dialog.vue @@ -1,53 +1,51 @@ diff --git a/app/components/HomeTable.vue b/app/components/HomeTable.vue new file mode 100644 index 0000000..3c76d21 --- /dev/null +++ b/app/components/HomeTable.vue @@ -0,0 +1,31 @@ + + + diff --git a/app/events/brapiDevEventEmitter.ts b/app/events/brapiDevEventEmitter.ts index c388b8c..3acb2c8 100644 --- a/app/events/brapiDevEventEmitter.ts +++ b/app/events/brapiDevEventEmitter.ts @@ -1,28 +1,32 @@ -import mitt, {type Emitter} from "mitt"; -import {useStocksCurrencyStore} from "@/stores/useStocksCurrencyStore"; -import type {Stock} from "@/types/BrapiDev/Stock"; +import mitt, { type Emitter } from "mitt"; +import { useStocksCurrencyStore } from "@/stores/useStocksCurrencyStore"; +import type { Stock } from "@/types/BrapiDev/Stock"; type BrapiDevEventEmitter = { - stocks: Stock[]; + stocks: Stock[]; }; const events = { - getCurrencyStocks: (payload: BrapiDevEventEmitter) => { - const stockStore = useStocksCurrencyStore(); - stockStore.addStocksCurrencies(payload.stocks); - }, + getCurrencyStocks: (payload: BrapiDevEventEmitter) => { + const stockStore = useStocksCurrencyStore(); + stockStore.addStocksCurrencies(payload.stocks); + }, + getHomeCurrencyStocks: (payload: BrapiDevEventEmitter) => { + const stockStore = useStocksCurrencyStore(); + stockStore.setHomeStockCurrencies(payload.stocks); + }, }; type EventSchema void>> = { - [K in keyof T]: Parameters[0]; + [ K in keyof T ]: Parameters[ 0 ]; }; type MittSchema = EventSchema< - typeof events & { - all: (payload: BrapiDevEventEmitter) => void; - } + typeof events & { + all: (payload: BrapiDevEventEmitter) => void; + } >; export const bus: Emitter = mitt(); bus.on("*", (type: unknown, payload) => { - events[type as keyof typeof events](payload); + events[ type as keyof typeof events ](payload); }); diff --git a/app/events/coinMarketCapEventEmitter.ts b/app/events/coinMarketCapEventEmitter.ts index 3ea21ae..2b3f6fd 100644 --- a/app/events/coinMarketCapEventEmitter.ts +++ b/app/events/coinMarketCapEventEmitter.ts @@ -1,28 +1,32 @@ -import mitt, {type Emitter} from "mitt"; -import {useCryptoCurrencyStore} from "@/stores/useCryptoCurrencyStore"; -import type {CryptoCurrency} from "@/types/CoinMarketCap/CryptoCurrency"; +import mitt, { type Emitter } from "mitt"; +import { useCryptoCurrencyStore } from "@/stores/useCryptoCurrencyStore"; +import type { CryptoCurrency } from "@/types/CoinMarketCap/CryptoCurrency"; type CoinMarketCapEventEmitter = { - crypto: CryptoCurrency[]; + crypto: CryptoCurrency[]; }; const events = { - getCurrencyCryptos: (payload: CoinMarketCapEventEmitter) => { - const cryptoStore = useCryptoCurrencyStore(); - cryptoStore.addCryptoCurrencies(payload.crypto); - }, + getCurrencyCryptos: (payload: CoinMarketCapEventEmitter) => { + const cryptoStore = useCryptoCurrencyStore(); + cryptoStore.addCryptoCurrencies(payload.crypto); + }, + getSortCurrencyCryptos: (payload: CoinMarketCapEventEmitter) => { + const cryptoStore = useCryptoCurrencyStore(); + cryptoStore.setHomeCryptoCurrencies(payload.crypto); + }, }; type EventSchema void>> = { - [K in keyof T]: Parameters[0]; + [ K in keyof T ]: Parameters[ 0 ]; }; type MittSchema = EventSchema< - typeof events & { - all: (payload: CoinMarketCapEventEmitter) => void; - } + typeof events & { + all: (payload: CoinMarketCapEventEmitter) => void; + } >; export const bus: Emitter = mitt(); bus.on("*", (type: unknown, payload) => { - events[type as keyof typeof events](payload); + events[ type as keyof typeof events ](payload); }); diff --git a/app/events/finnhubEventEmitter.ts b/app/events/finnhubEventEmitter.ts index 1c28f6a..22a1204 100644 --- a/app/events/finnhubEventEmitter.ts +++ b/app/events/finnhubEventEmitter.ts @@ -1,30 +1,30 @@ -import mitt, {type Emitter} from "mitt"; -import {useNewsStore} from "@/stores/useNewsStore"; -import type {Category} from "@/types/Finnhub/Category"; -import type {New} from "@/types/Finnhub/New"; +import mitt, { type Emitter } from "mitt"; +import { useNewsStore } from "@/stores/useNewsStore"; +import type { Category } from "@/types/Finnhub/Category"; +import type { New } from "@/types/Finnhub/New"; type FinnhubEventEmitter = { - category: Category; - news: New[]; + category: Category; + news: New[]; }; const events = { - getMarketNews: (payload: FinnhubEventEmitter) => { - const newsStore = useNewsStore(); - newsStore.addNews(payload.news, payload.category); - }, + getMarketNews: (payload: FinnhubEventEmitter) => { + const newsStore = useNewsStore(); + newsStore.addNews(payload.news, payload.category); + }, }; type EventSchema void>> = { - [K in keyof T]: Parameters[0]; + [ K in keyof T ]: Parameters[ 0 ]; }; type MittSchema = EventSchema< - typeof events & { - all: (payload: FinnhubEventEmitter) => void; - } + typeof events & { + all: (payload: FinnhubEventEmitter) => void; + } >; export const bus: Emitter = mitt(); bus.on("*", (type: unknown, payload) => { - events[type as keyof typeof events](payload); + events[ type as keyof typeof events ](payload); }); diff --git a/app/services/BrapiDev.ts b/app/services/BrapiDev.ts index 902cab1..60e0150 100644 --- a/app/services/BrapiDev.ts +++ b/app/services/BrapiDev.ts @@ -1,6 +1,8 @@ -import {bus} from "@/events/brapiDevEventEmitter"; -import {get} from "@/server/HttpClient"; -import type {Stock} from "@/types/BrapiDev/Stock"; +import { bus } from "@/events/brapiDevEventEmitter"; +import { get } from "@/server/HttpClient"; +import type { SortBy } from "@/types/BrapiDev/SortBy"; +import type { SortOrder } from "@/types/BrapiDev/SortOrder"; +import type { Stock } from "@/types/BrapiDev/Stock"; /** * @description Handles the request to get the list of currency quotes. @@ -10,18 +12,29 @@ import type {Stock} from "@/types/BrapiDev/Stock"; * @returns Promise * @throws {Error} If the request to the proxy fails */ -export async function listStocks(limit = 12, page = 1): Promise { - try { - const response = await get(`/api/quote/list?limit=${limit}&page=${page}`); +export async function listStocks(limit = 12, page = 1, sortBy?: SortBy, sortOrder?: SortOrder): Promise { + let url: string; - if (!response.ok) throw new Error(await response.json()); + if (sortBy && sortOrder) { + url = `/api/quote/list?limit=${limit}&page=${page}&sortBy=${sortBy}&sortOrder=${sortOrder}`; + } else { + url = `/api/quote/list?limit=${limit}&page=${page}`; + } + try { + const response = await get(url); - const stocks: Stock[] = await response.json(); + if (!response.ok) throw new Error(await response.json()); - bus.emit("getCurrencyStocks", {stocks}); + const stocks: Stock[] = await response.json(); - return stocks; - } catch (error) { - console.error(error); - } + if (!sortBy && !sortOrder) { + bus.emit("getCurrencyStocks", { stocks }); + } else { + bus.emit("getHomeCurrencyStocks", { stocks }); + } + + return stocks; + } catch (error) { + console.error(error); + } } diff --git a/app/services/CoinMarketCap.ts b/app/services/CoinMarketCap.ts index 2813ae6..812c4f0 100644 --- a/app/services/CoinMarketCap.ts +++ b/app/services/CoinMarketCap.ts @@ -1,31 +1,45 @@ -import {bus} from "@/events/coinMarketCapEventEmitter"; -import {get} from "@/server/HttpClient"; -import type {CryptoCurrency} from "@/types/CoinMarketCap/CryptoCurrency"; +import { bus } from "@/events/coinMarketCapEventEmitter"; +import { get } from "@/server/HttpClient"; +import type { Sort } from "@/types/CoinMarketCap/Sort"; +import type { CryptoCurrency } from "@/types/CoinMarketCap/CryptoCurrency"; /** * @description Handles the request to get the latest cryptocurrency listings. * * @param {number} limit - The limit number of cryptocurrencies to return * @param {number} start - The start number of cryptocurrencies to return + * @param {string} sort - The sort order of cryptocurrencies to return * @returns Promise * @throws {Error} If the request to the proxy fails */ -export async function listBitcoin(limit = 12, start = 1): Promise { - try { - const response = await get( - `/v1/cryptocurrency/listings/latest?limit=${limit}&start=${start}`, - ); +export async function listBitcoin(limit = 12, start = 1, sort?: Sort): Promise { + let url: string; - if (!response.ok) throw new Error(await response.json()); + if (sort) { + url = `/v1/cryptocurrency/listings/latest?limit=${limit}&start=${start}&sort=${sort}`; + } else { + url = `/v1/cryptocurrency/listings/latest?limit=${limit}&start=${start}`; + } + try { - const crypto: CryptoCurrency[] = await response.json(); + const response = await get( + url + ); - bus.emit("getCurrencyCryptos", {crypto}); + if (!response.ok) throw new Error(await response.json()); - return crypto; - } catch (error) { - console.error(error); - } + const crypto: CryptoCurrency[] = await response.json(); + + if (!sort) { + bus.emit("getCurrencyCryptos", { crypto }); + } else { + bus.emit("getSortCurrencyCryptos", { crypto }); + } + + return crypto; + } catch (error) { + console.error(error); + } } /** @@ -36,15 +50,15 @@ export async function listBitcoin(limit = 12, start = 1): Promise { - try { - const response = await get(`/v2/cryptocurrency/info?slug=${slug}`); + try { + const response = await get(`/v2/cryptocurrency/info?slug=${slug}`); - if (!response.ok) throw new Error(await response.json()); + if (!response.ok) throw new Error(await response.json()); - const jsonData: CryptoCurrency = await response.json(); + const jsonData: CryptoCurrency = await response.json(); - return jsonData; - } catch (error) { - console.error(error); - } + return jsonData; + } catch (error) { + console.error(error); + } } diff --git a/app/services/Finnhub.ts b/app/services/Finnhub.ts index ec8618e..0012263 100644 --- a/app/services/Finnhub.ts +++ b/app/services/Finnhub.ts @@ -1,7 +1,8 @@ -import {get} from "@/server/HttpClient"; -import type {Category} from "@/types/Finnhub/Category"; -import type {New} from "@/types/Finnhub/New"; -import {bus} from "@/events/finnhubEventEmitter"; +import { get } from "@/server/HttpClient"; +import type { Category } from "@/types/Finnhub/Category"; +import type { New } from "@/types/Finnhub/New"; +import { bus } from "@/events/finnhubEventEmitter"; +import formatDate from "@/utils/formatDate"; /** * @description Handles the request to get the list of market news. @@ -11,18 +12,51 @@ import {bus} from "@/events/finnhubEventEmitter"; * @throws {Error} If the request to the proxy fails */ export async function listMarketNews(category: Category = "crypto"): Promise { - const url = `/api/v1/news?category=${category}`; - try { - const response = await get(url); + const url = `/api/v1/news?category=${category}`; + try { + const response = await get(url); - if (!response.ok) throw new Error(await response.json()); + if (!response.ok) throw new Error(await response.json()); - const news: New[] = await response.json(); + const news: New[] = await response.json(); - bus.emit("getMarketNews", {category, news}); + bus.emit("getMarketNews", { category, news }); - return news; - } catch (error) { - console.error(error); - } + return news; + } catch (error) { + console.error(error); + } +} + +/** + * @description Handles the request to get the list of company news. + * + * @param {string} symbol - The symbol of the news + * @returns Promise + * @throws {Error} If the request to the proxy fails + */ +export async function listCompanyNews(symbol = "AAPL"): Promise { + const from = new Date(); + const to = new Date(); + + from.setMonth(from.getMonth() - 1); + + const formattedFrom = formatDate(from); + const formattedTo = formatDate(to); + + const url = `/api/v1/company-news?symbol=${symbol}&from=${formattedFrom}&to=${formattedTo}`; + + try { + const response = await get(url); + + if (!response.ok) throw new Error(await response.json()); + + const news: New[] = await response.json(); + + bus.emit("getMarketNews", { category: "company", news }); + + return news; + } catch (error) { + console.error(error); + } } diff --git a/app/stores/useCryptoCurrencyStore.ts b/app/stores/useCryptoCurrencyStore.ts index 65095c0..956887d 100644 --- a/app/stores/useCryptoCurrencyStore.ts +++ b/app/stores/useCryptoCurrencyStore.ts @@ -1,35 +1,42 @@ -import {ref} from "vue"; -import {defineStore} from "pinia"; +import { ref } from "vue"; +import { defineStore } from "pinia"; -import type {CryptoCurrency} from "@/types/CoinMarketCap/CryptoCurrency"; +import type { CryptoCurrency } from "@/types/CoinMarketCap/CryptoCurrency"; export const useCryptoCurrencyStore = defineStore("cryptoCurrency", () => { - const cryptoCurrencies = ref([]); + const cryptoCurrencies = ref([]); + const homeCryptoCurrencies = ref([]); - function addCryptoCurrencies(cryptoCurrencyArray: CryptoCurrency[]): void { - cryptoCurrencies.value.push(...cryptoCurrencyArray); - } + function setHomeCryptoCurrencies(cryptoCurrencyArray: CryptoCurrency[]): void { + homeCryptoCurrencies.value = cryptoCurrencyArray; + } - function removeCryptoCurrency(id: string): void { - cryptoCurrencies.value = cryptoCurrencies.value.filter( - (cryptoCurrency) => cryptoCurrency.id.toString() !== id, - ); - } + function addCryptoCurrencies(cryptoCurrencyArray: CryptoCurrency[]): void { + cryptoCurrencies.value.push(...cryptoCurrencyArray); + } - function detailCryptoCurrencyByName(name: string): CryptoCurrency | null { - const cryptoCurrency = cryptoCurrencies.value.find( - (cryptoCurrency) => cryptoCurrency.name === name, - ); - if (!cryptoCurrency) { - return null; - } - return cryptoCurrency; - } + function removeCryptoCurrency(id: string): void { + cryptoCurrencies.value = cryptoCurrencies.value.filter( + (cryptoCurrency) => cryptoCurrency.id.toString() !== id, + ); + } - return { - cryptoCurrencies, - addCryptoCurrencies, - removeCryptoCurrency, - detailCryptoCurrencyByName, - }; + function detailCryptoCurrencyByName(name: string): CryptoCurrency | null { + const cryptoCurrency = cryptoCurrencies.value.find( + (cryptoCurrency) => cryptoCurrency.name === name, + ); + if (!cryptoCurrency) { + return null; + } + return cryptoCurrency; + } + + return { + cryptoCurrencies, + homeCryptoCurrencies, + setHomeCryptoCurrencies, + addCryptoCurrencies, + removeCryptoCurrency, + detailCryptoCurrencyByName, + }; }); diff --git a/app/stores/useCurrencyQuotesStore.ts b/app/stores/useCurrencyQuotesStore.ts index 3431803..2afe619 100644 --- a/app/stores/useCurrencyQuotesStore.ts +++ b/app/stores/useCurrencyQuotesStore.ts @@ -1,32 +1,32 @@ -import {ref} from "vue"; -import {defineStore} from "pinia"; -import type {CurrencyQuotes} from "@/types/CurrencyQuotes/CurrencyQuotes"; -import type {Rates} from "@/types/CurrencyQuotes/Rates"; +import { ref } from "vue"; +import { defineStore } from "pinia"; +import type { CurrencyQuotes } from "@/types/CurrencyQuotes/CurrencyQuotes"; +import type { Rates } from "@/types/CurrencyQuotes/Rates"; export const useCurrencyQuotesStore = defineStore("currencyQuotes", () => { - const currencyQuotes = ref(); - const currency = ref(1); - const leftCode = ref("USD"); - const rightCode = ref("BRL"); + const currencyQuotes = ref(); + const currency = ref(1); + const leftCode = ref("USD"); + const rightCode = ref("BRL"); - function setCurrencyQuotes(quotes: CurrencyQuotes): void { - currencyQuotes.value = quotes; - } + function setCurrencyQuotes(quotes: CurrencyQuotes): void { + currencyQuotes.value = quotes; + } - function invertCodes(): void { - const lastRightCode = rightCode.value; - const lastLeftCode = leftCode.value; + function invertCodes(): void { + const lastRightCode = rightCode.value; + const lastLeftCode = leftCode.value; - leftCode.value = lastRightCode; - rightCode.value = lastLeftCode; - } + leftCode.value = lastRightCode; + rightCode.value = lastLeftCode; + } - return { - currencyQuotes, - currency, - leftCode, - rightCode, - setCurrencyQuotes, - invertCodes, - }; + return { + currencyQuotes, + currency, + leftCode, + rightCode, + setCurrencyQuotes, + invertCodes, + }; }); diff --git a/app/stores/useNewsStore.ts b/app/stores/useNewsStore.ts index 5400f58..76ea2e3 100644 --- a/app/stores/useNewsStore.ts +++ b/app/stores/useNewsStore.ts @@ -1,26 +1,27 @@ -import {ref} from "vue"; -import {defineStore} from "pinia"; -import type {New} from "@/types/Finnhub/New"; -import type {Category} from "@/types/Finnhub/Category"; +import { ref } from "vue"; +import { defineStore } from "pinia"; +import type { New } from "@/types/Finnhub/New"; +import type { Category } from "@/types/Finnhub/Category"; type CategoriesNews = { - [key in Category]: New[]; + [ key in Category ]: New[]; }; export const useNewsStore = defineStore("news", () => { - const news = ref({ - crypto: [], - forex: [], - general: [], - merger: [], - }); + const news = ref({ + crypto: [], + forex: [], + general: [], + merger: [], + company: [], + }); - function addNews(data: New[], category: Category): void { - news.value[category].push(...data); - } + function addNews(data: New[], category: Category): void { + news.value[ category ].push(...data); + } - return { - news, - addNews, - }; + return { + news, + addNews, + }; }); diff --git a/app/stores/useStocksCurrencyStore.ts b/app/stores/useStocksCurrencyStore.ts index 24ce744..690dd93 100644 --- a/app/stores/useStocksCurrencyStore.ts +++ b/app/stores/useStocksCurrencyStore.ts @@ -1,28 +1,35 @@ -import {ref} from "vue"; -import {defineStore} from "pinia"; +import { ref } from "vue"; +import { defineStore } from "pinia"; -import type {Stock} from "@/types/BrapiDev/Stock"; +import type { Stock } from "@/types/BrapiDev/Stock"; export const useStocksCurrencyStore = defineStore("stocksCurrency", () => { - const stocksCurrencies = ref([]); + const stocksCurrencies = ref([]); + const homeStockCurrencies = ref([]); - function addStocksCurrencies(stockCurrencyArray: Stock[]): void { - stocksCurrencies.value.push(...stockCurrencyArray); - } + function setHomeStockCurrencies(stockCurrencyArray: Stock[]): void { + homeStockCurrencies.value = stockCurrencyArray; + } - function detailStocksCurrency(name: string): Stock | null { - const stocksCurrency = stocksCurrencies.value.find( - (stocksCurrency) => stocksCurrency.name === name, - ); - if (!stocksCurrency) { - return null; - } - return stocksCurrency; - } + function addStocksCurrencies(stockCurrencyArray: Stock[]): void { + stocksCurrencies.value.push(...stockCurrencyArray); + } - return { - stocksCurrencies, - addStocksCurrencies, - detailStocksCurrency, - }; + function detailStocksCurrency(name: string): Stock | null { + const stocksCurrency = stocksCurrencies.value.find( + (stocksCurrency) => stocksCurrency.name === name, + ); + if (!stocksCurrency) { + return null; + } + return stocksCurrency; + } + + return { + stocksCurrencies, + homeStockCurrencies, + setHomeStockCurrencies, + addStocksCurrencies, + detailStocksCurrency, + }; }); diff --git a/app/types/BrapiDev/SortBy.ts b/app/types/BrapiDev/SortBy.ts new file mode 100644 index 0000000..cd2bfae --- /dev/null +++ b/app/types/BrapiDev/SortBy.ts @@ -0,0 +1 @@ +export type SortBy = "name" | "close" | "change" | "change_abs" | "volume" | "market_cap_basic"; diff --git a/app/types/BrapiDev/SortOrder.ts b/app/types/BrapiDev/SortOrder.ts new file mode 100644 index 0000000..4b12a7d --- /dev/null +++ b/app/types/BrapiDev/SortOrder.ts @@ -0,0 +1 @@ +export type SortOrder = "asc" | "desc"; diff --git a/app/types/CoinMarketCap/Sort.ts b/app/types/CoinMarketCap/Sort.ts new file mode 100644 index 0000000..d564c91 --- /dev/null +++ b/app/types/CoinMarketCap/Sort.ts @@ -0,0 +1 @@ +export type Sort = "name" | "symbol" | "date_added" | "market_cap" | "market_cap_strict" | "price" | "circulating_supply" | "total_supply" | "max_supply" | "num_market_pairs" | "volume_24h" | "percent_change_1h" | "percent_change_24h" | "percent_change_7d" | "market_cap_by_total_supply_strict" | "volume_7d" | " volume_30d" diff --git a/app/types/Finnhub/Category.ts b/app/types/Finnhub/Category.ts index b14275b..e082278 100644 --- a/app/types/Finnhub/Category.ts +++ b/app/types/Finnhub/Category.ts @@ -1 +1 @@ -export type Category = "general" | "forex" | "crypto" | "merger"; +export type Category = "general" | "forex" | "crypto" | "merger" | "company"; diff --git a/app/utils/formatDate.ts b/app/utils/formatDate.ts new file mode 100644 index 0000000..f1b3bd2 --- /dev/null +++ b/app/utils/formatDate.ts @@ -0,0 +1,12 @@ +/** + * @description Function to format a date to the format YYYY-MM-DD. + * + * @param {Date} date - The date to format + * @returns string + */ +export default function formatDate(date: Date): string { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; +} diff --git a/app/views/Home.vue b/app/views/Home.vue index acfb41a..29c5467 100644 --- a/app/views/Home.vue +++ b/app/views/Home.vue @@ -1,17 +1,33 @@