Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Front #72

Merged
merged 17 commits into from
Jan 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx commitlint --edit $1
# npx commitlint --edit $1
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run format && npm run lint && git add .
# npm run format && npm run lint
13 changes: 7 additions & 6 deletions back/src/controllers/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ controller.post('/login', async (req, res) => {
});

return res.status(HttpStatusCode.OK_200).send({
user: {
id: key.userId,
email: body.data.email,
},
token: session.sessionId,
});
user: {
id: key.userId,
email: body.data.email,
is_admin: session.user.is_admin,
},
token: session.sessionId,
});
});

controller.post('/register', async (req, res) => {
Expand Down
244 changes: 144 additions & 100 deletions back/src/controllers/cryptos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,137 +3,181 @@ import HttpStatusCode from '#types/HttpStatusCode';
import UrlParamIdDTO from '#types/dto/UrlParamIdDTO';
import UrlQueryIdListDTO from '#types/dto/UrlQueryIdListDTO';

import express from 'express';
import useCrypto from '@composables/useCrypto';
import useCrypto from "@composables/useCrypto";
import express from "express";

import CreateCryptoDto from '#types/dto/cryptos/CreateCryptoDTO';
import UpdateCryptoDto from '#types/dto/cryptos/UpdateCryptoDTO';

import {
createCrypto,
deleteCryptoById,
updateCryptoById,
findManyCryptosById,
findAllVisibleCryptos,
findCryptoById,
} from '@database/cryptos';

import { adminRoleRequired, authenticationRequired } from '~middlewares';
import HistoryParamDTO from '#types/dto/cryptos/HistoryParamDTO';
createCrypto,
deleteCryptoById,
findAllCryptos,
findAllVisibleCryptos,
findCryptoById,
findManyCryptosById,
updateCryptoById,
} from "@database/cryptos";

import HistoryParamDTO from "#types/dto/cryptos/HistoryParamDTO";
import { adminRoleRequired, authenticationRequired } from "~middlewares";

const { getAllCrypto, getCrypto, getHistory } = useCrypto();
const controller = express.Router();

controller.get('/', async (req, res) => {
const query = UrlQueryIdListDTO.parse(req.query);
const currency = req.lucia ? req.lucia.user.currency : 'EUR';
controller.get("/", async (req, res) => {
const query = UrlQueryIdListDTO.parse(req.query);
const currency = req.lucia ? req.lucia.user.currency : "EUR";

const cryptos = query.ids
? await findManyCryptosById(query.ids)
: await findAllVisibleCryptos();
const cryptos = query.ids
? await findManyCryptosById(query.ids)
: await findAllVisibleCryptos();

const tickers: string[] = [];
const tickers: string[] = [];

const cryptoWithTicker = cryptos.map((crypto) => {
const ticker = `${crypto.api_id}/${currency}`;
const cryptoWithTicker = cryptos.map((crypto) => {
const ticker = `${crypto.api_id}/${currency}`;

tickers.push(ticker);
return { ticker, ...crypto };
});
tickers.push(ticker);
return { ticker, ...crypto };
});

if (tickers.length === 0) {
return res.status(HttpStatusCode.OK_200).json([]);
}
if (tickers.length === 0) {
return res.status(HttpStatusCode.OK_200).json([]);
}

const apiResponse = await getAllCrypto(tickers);
const apiResponse = await getAllCrypto(tickers);

const response = cryptoWithTicker.map((crypto) => {
const data = apiResponse[crypto.ticker];
const response = cryptoWithTicker.map((crypto) => {
const data = apiResponse[crypto.ticker];

if (!data) {
return;
}
if (!data) {
return;
}

return {
name: crypto.name,
current_price: data.last,
opening_price: data.open,
lowest_price: data.low,
highest_price: parseFloat(data.info.highPrice),
image: crypto.logo_url,
};
});
return {
id: crypto.id,
name: crypto.name,
current_price: data.last,
opening_price: data.open,
lowest_price: data.low,
highest_price: parseFloat(data.info.highPrice),
image: crypto.logo_url,
is_visible: crypto.visible,
};
});

return res.status(HttpStatusCode.OK_200).send(response);
return res.status(HttpStatusCode.OK_200).send(response);
});
controller.get("/list", async (req, res) => {
const query = UrlQueryIdListDTO.parse(req.query);
const currency = req.lucia ? req.lucia.user.currency : "EUR";

controller.get('/:id', authenticationRequired, async (req, res) => {
const params = UrlParamIdDTO.parse(req.params);
const currency = req.lucia ? req.lucia.user.currency : 'EUR';

const crypto = await findCryptoById(params.id);
const apiResponse = await getCrypto(`${crypto.api_id}/${currency}`);

return res.status(HttpStatusCode.OK_200).send({
name: crypto.name,
current_price: apiResponse.last,
opening_price: apiResponse.open,
lowest_price: apiResponse.low,
highest_price: apiResponse.high,
image: crypto.logo_url,
});
});
const cryptos = query.ids
? await findManyCryptosById(query.ids)
: await findAllCryptos();

controller.get(
'/:id/history/:period',
authenticationRequired,
async (req, res) => {
const params = HistoryParamDTO.parse(req.params);
const currency = req.lucia ? req.lucia.user.currency : 'EUR';
const tickers: string[] = [];

const crypto = await findCryptoById(params.id);
const apiResponse = await getHistory(
`${crypto.api_id}/${currency}`,
params.period,
);
const cryptoWithTicker = cryptos.map((crypto) => {
const ticker = `${crypto.api_id}/${currency}`;

console.log(apiResponse.length);
tickers.push(ticker);
return { ticker, ...crypto };
});

return res.status(HttpStatusCode.OK_200).send(apiResponse);
},
if (tickers.length === 0) {
return res.status(HttpStatusCode.OK_200).json([]);
}

const apiResponse = await getAllCrypto(tickers);

const response = cryptoWithTicker.map((crypto) => {
const data = apiResponse[crypto.ticker];

if (!data) {
return;
}

return {
id: crypto.id,
name: crypto.name,
image: crypto.logo_url,
is_visible: crypto.visible,
};
});

return res.status(HttpStatusCode.OK_200).send(response);
});

controller.get("/:id", authenticationRequired, async (req, res) => {
const params = UrlParamIdDTO.parse(req.params);
const currency = req.lucia ? req.lucia.user.currency : "EUR";

const crypto = await findCryptoById(params.id);
const apiResponse = await getCrypto(`${crypto.api_id}/${currency}`);

return res.status(HttpStatusCode.OK_200).send({
name: crypto.name,
current_price: apiResponse.last,
opening_price: apiResponse.open,
lowest_price: apiResponse.low,
highest_price: apiResponse.high,
image: crypto.logo_url,
});
});

controller.get(
"/:id/history/:period",
authenticationRequired,
async (req, res) => {
const params = HistoryParamDTO.parse(req.params);
const currency = req.lucia ? req.lucia.user.currency : "EUR";

const crypto = await findCryptoById(params.id);
const apiResponse = await getHistory(
`${crypto.api_id}/${currency}`,
params.period
);

console.log(apiResponse.length);

return res.status(HttpStatusCode.OK_200).send(apiResponse);
}
);

controller.post(
'/',
authenticationRequired,
adminRoleRequired,
async (req, res) => {
const body = CreateCryptoDto.parse(req.body);
const createdCrypto = await createCrypto({
name: body.name,
api_id: body.apiId,
logo_url: body.logoUrl,
visible: body.visible,
});
return res.status(HttpStatusCode.CREATED_201).send(createdCrypto);
},
"/",
authenticationRequired,
adminRoleRequired,
async (req, res) => {
const body = CreateCryptoDto.parse(req.body);
const createdCrypto = await createCrypto({
name: body.name,
api_id: body.apiId,
logo_url: body.logoUrl,
visible: body.visible,
});
return res.status(HttpStatusCode.CREATED_201).send(createdCrypto);
}
);

controller.put(
'/:id',
authenticationRequired,
adminRoleRequired,
async (req, res) => {
const urlParams = UrlParamIdDTO.parse(req.params);
const body = UpdateCryptoDto.parse(req.body);
const createdCrypto = await updateCryptoById(urlParams.id, {
name: body.name,
api_id: body.apiId,
logo_url: body.logoUrl,
visible: body.visible,
});
return res.status(HttpStatusCode.OK_200).send(createdCrypto);
},
"/:id",
authenticationRequired,
adminRoleRequired,
async (req, res) => {
const urlParams = UrlParamIdDTO.parse(req.params);

const body = UpdateCryptoDto.parse(req.body);
const createdCrypto = await updateCryptoById(urlParams.id, {
name: body.name,
api_id: body.apiId,
logo_url: body.logoUrl,
visible: body.visible,
});
return res.status(HttpStatusCode.OK_200).send(createdCrypto);
}
);

controller.delete(
Expand Down
4 changes: 4 additions & 0 deletions back/src/database/cryptos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,7 @@ export async function findAllVisibleCryptos() {
where: { visible: true },
});
}

export async function findAllCryptos() {
return await database.crypto.findMany({});
}
18 changes: 18 additions & 0 deletions front/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}
41 changes: 21 additions & 20 deletions front/.gitignore
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
Loading