From 6b1719987abac71a899ea638b07e6662b54250a4 Mon Sep 17 00:00:00 2001 From: Julien Calixte Date: Thu, 19 Sep 2019 19:28:00 +0200 Subject: [PATCH] :sparkles: (Account Card) Design Card --- package-lock.json | 11 +++ package.json | 2 + src/components/AccountCard.vue | 99 ++++++++++++++++++++-- src/services/TransactionService.ts | 6 +- src/views/transactions/TransactionItem.vue | 83 ++++++++++++------ 5 files changed, 169 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index de9b336..4c783a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1052,6 +1052,12 @@ } } }, + "@types/chartist": { + "version": "0.9.46", + "resolved": "https://registry.npmjs.org/@types/chartist/-/chartist-0.9.46.tgz", + "integrity": "sha512-p29+DAkJRBVtuiTx5kObF6n/RipOWH0GeWVwYinljrwPMruy7BW+Ms6iHS4vIsHzb9c79x+opon3GJo75rlhcQ==", + "dev": true + }, "@types/debug": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz", @@ -3478,6 +3484,11 @@ "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" }, + "chartist": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/chartist/-/chartist-0.11.4.tgz", + "integrity": "sha512-H4AimxaUD738/u9Mq8t27J4lh6STsLi4BQHt65nOtpLk3xyrBPaLiLMrHw7/WV9CmsjGA02WihjuL5qpSagLYw==" + }, "check-types": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz", diff --git a/package.json b/package.json index 0bac07f..b0d2bc4 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "bulma-checkradio": "^2.1.0", "bulma-pricingtable": "^0.2.0", "bulma-switch": "^2.0.0", + "chartist": "^0.11.4", "crypto-js": "^3.1.9-1", "lightness": "^1.0.0", "lodash-es": "^4.17.15", @@ -39,6 +40,7 @@ "vuex-persist": "^2.0.1" }, "devDependencies": { + "@types/chartist": "^0.9.46", "@types/jest": "^24.0.17", "@types/lodash-es": "^4.17.3", "@types/md5": "^2.1.33", diff --git a/src/components/AccountCard.vue b/src/components/AccountCard.vue index 62b7802..2288b42 100644 --- a/src/components/AccountCard.vue +++ b/src/components/AccountCard.vue @@ -1,15 +1,21 @@ @@ -21,11 +27,51 @@ import accountService from '@/services/AccountService' import IAccount from '@/models/IAccount' import IColor from '@/models/IColor' import FabButton from '@/components/FabButton.vue' +import ITransaction from '../models/ITransaction' +import TransactionService from '../services/TransactionService' +import Chartist from 'chartist' +import TransactionType from '../enums/TransactionType' +import colors from '../data/colors' @Component export default class AccountCard extends Vue { @Prop({ type: Object, required: true }) public account!: IAccount + public transactions: ITransaction[] = [] + + public async mounted() { + this.transactions = await TransactionService.getAllByAccountId( + this.account._id + ) + + const data = { + labels: this.labels, + series: [this.sumOfTransactions] + } + + const chartId = `#chart-${this.account._id}` + // tslint:disable-next-line:no-unused-expression + new Chartist.Bar(chartId, data, {}) + + setTimeout(() => { + const color = colors.find((c) => c.value === this.account.color) + if (!color) { + return + } + const bars = document.querySelectorAll( + `${chartId} .ct-bar` + ) as NodeListOf + bars.forEach((bar) => (bar.style.stroke = color.darkValue || 'red')) + }, 500) + } + + public findDarkValue(color: string): string | null { + return findDarkValue(color) + } + + public goToAccount(id: string): void { + this.$router.push({ name: 'account', params: { id } }) + } public getColor(color: string | null): any | null { if (!color) { @@ -37,18 +83,57 @@ export default class AccountCard extends Vue { } } - public findDarkValue(color: string): string | null { - return findDarkValue(color) + public get amounts(): ITransaction[] { + return this.transactions.filter( + (transaction) => transaction.transactionType === TransactionType.normal + ) } - public goToAccount(id: string): void { - this.$router.push({ name: 'account', params: { id } }) + public get labels(): string[] { + const dates = this.amounts.map((transaction) => + this.dateToLabel(new Date(transaction.date)) + ) + return [...new Set(dates)] + } + + public get sumOfTransactions(): number[] { + const sortedTransactions = [...this.amounts].sort((a, b) => + a.date < b.date ? -1 : 1 + ) + const groups = sortedTransactions.reduce( + (group: { [key: string]: number }, transaction: ITransaction) => { + const date = this.dateToLabel(new Date(transaction.date)) + if (!(date in group)) { + group[date] = 0 + } + group[date] += transaction.amount + return group + }, + {} + ) + return Object.values(groups) + } + + private dateToLabel(date: Date): string { + return `${(date.getMonth() + 1) + .toString() + .padStart(2, '0')}/${date.getFullYear()}` } }