diff options
Diffstat (limited to 'public/projects/js-small-apps/budget-app/lib')
7 files changed, 516 insertions, 0 deletions
diff --git a/public/projects/js-small-apps/budget-app/lib/class-budget-app.js b/public/projects/js-small-apps/budget-app/lib/class-budget-app.js new file mode 100644 index 0000000..45097a0 --- /dev/null +++ b/public/projects/js-small-apps/budget-app/lib/class-budget-app.js @@ -0,0 +1,144 @@ +import Category from "./class-category.js"; +import Transaction from "./class-transaction.js"; +import User from "./class-user.js"; + +class BudgetApp { + #title = "Budget App"; + #categoryId = 1; + #categories = []; + #transactionId = 1; + #incomes = []; + #expenses = []; + #userId = 1; + #user = {}; + + constructor(title, username) { + this.#title = title; + this.#user = new User(this.#userId++, username); + } + + set title(string) { + this.#title = string; + } + + get title() { + return this.#title; + } + + set categories(array) { + this.#categories = array; + } + + get categories() { + return this.#categories; + } + + set incomes(array) { + this.#incomes = array; + } + + get incomes() { + return this.#incomes; + } + + set expenses(array) { + this.#expenses = array; + } + + get expenses() { + return this.#expenses; + } + + set user(username) { + this.#user = new User(this.#userId++, username); + } + + get user() { + return this.#user; + } + + remove(id, from) { + const index = from.findIndex((object) => object.id === id); + from.splice(index, 1); + } + + addCategory(name) { + this.#categories.push(new Category(this.#categoryId++, name)); + } + + renameCategory(id, newName) { + const index = this.categories.findIndex((object) => object.id === id); + this.categories[index].name = newName; + } + + addTransaction(transaction) { + const array = + transaction.type === "income" ? this.#incomes : this.#expenses; + array.push( + new Transaction( + this.#transactionId++, + transaction.date, + transaction.name, + transaction.type, + transaction.category, + transaction.amount + ) + ); + } + + editTransaction(transaction) { + const array = transaction.type === "income" ? this.incomes : this.expenses; + const index = array.findIndex((object) => { + return object.id === Number(transaction.id); + }); + if (index !== -1) { + array[index] = new Transaction(...Object.values(transaction)); + } else { + const oldArray = array === this.incomes ? this.expenses : this.incomes; + array.push(new Transaction(...Object.values(transaction))); + this.remove(transaction.id, oldArray); + } + } + + getOrderedTransactions(order) { + const transactions = [...this.expenses, ...this.incomes]; + + switch (order) { + case "newest": + transactions.sort((a, b) => b.date - a.date); + break; + case "oldest": + transactions.sort((a, b) => a.date - b.date); + break; + default: + break; + } + + return transactions; + } + + total(transaction) { + const array = transaction === "expense" ? this.#expenses : this.#incomes; + let total = 0; + array.forEach((item) => { + total += item.amount; + }); + return total; + } + + updateUserBudget() { + this.user.budget.spent = this.total("expense"); + this.user.budget.profit = this.total("income"); + } + + reset() { + this.#categoryId = 1; + this.#transactionId = 1; + this.#categories = []; + this.#incomes = []; + this.#expenses = []; + this.updateUserBudget(); + } +} + +export default BudgetApp; diff --git a/public/projects/js-small-apps/budget-app/lib/class-budget.js b/public/projects/js-small-apps/budget-app/lib/class-budget.js new file mode 100644 index 0000000..cde22fd --- /dev/null +++ b/public/projects/js-small-apps/budget-app/lib/class-budget.js @@ -0,0 +1,44 @@ +/** + * Budget class + * + * Create a new budget. + */ +class Budget { + #initial = 0; + #spent = 0; + #profit = 0; + + constructor(initial) { + this.#initial = Number.parseFloat(initial); + } + + set initial(number) { + this.#initial = Number.parseFloat(number); + } + + get initial() { + return this.#initial; + } + + set spent(number) { + this.#spent = Number.parseFloat(number); + } + + get spent() { + return this.#spent; + } + + set profit(number) { + this.#profit = Number.parseFloat(number); + } + + get profit() { + return this.#profit; + } + + remaining() { + return this.initial + this.profit - this.spent; + } +} + +export default Budget; diff --git a/public/projects/js-small-apps/budget-app/lib/class-category.js b/public/projects/js-small-apps/budget-app/lib/class-category.js new file mode 100644 index 0000000..7b2f1b2 --- /dev/null +++ b/public/projects/js-small-apps/budget-app/lib/class-category.js @@ -0,0 +1,37 @@ +/** + * Category class. + * + * Create a new category with id, name and attachments. + */ +class Category { + #id = 0; + #name = ""; + #attachments = []; + + constructor(id, name) { + this.#id = Number(id); + this.#name = name; + } + + set name(name) { + this.#name = name; + } + + get name() { + return this.#name; + } + + get id() { + return this.#id; + } + + set attachments(attachment) { + this.#attachments.push(Number(attachment)); + } + + get attachments() { + return this.#attachments; + } +} + +export default Category; diff --git a/public/projects/js-small-apps/budget-app/lib/class-notification.js b/public/projects/js-small-apps/budget-app/lib/class-notification.js new file mode 100644 index 0000000..17a32a0 --- /dev/null +++ b/public/projects/js-small-apps/budget-app/lib/class-notification.js @@ -0,0 +1,89 @@ +class Notification { + #id = 0; + #title = ""; + #message = ""; + #type = ""; + #duration = 0; + #position = ""; + + constructor(message, type) { + this.#message = message; + this.#type = type; + } + + get id() { + return this.#id; + } + + set title(string) { + this.#title = string; + } + + get title() { + return this.#title; + } + + set message(text) { + this.#message = text; + } + + get message() { + return this.#message; + } + + set type(string) { + this.#type = string; + } + + get type() { + return this.#type; + } + + set duration(number) { + this.#duration = number; + } + + get duration() { + return this.#duration; + } + + set position(string) { + this.#position = string; + } + + get position() { + return this.#position; + } + + #getWrapper() { + let wrapper = document.getElementById("notifications-center"); + + if (!wrapper) { + wrapper = document.createElement("div"); + wrapper.id = "notifications-center"; + wrapper.classList = "notifications"; + document.body.appendChild(wrapper); + } + + return wrapper; + } + + notify() { + const notification = document.createElement("div"); + notification.textContent = this.message; + notification.classList.add("notification", `notification--${this.type}`); + + const wrapper = this.#getWrapper(); + document.body.style.position = "relative"; + wrapper.style.cssText = `position: fixed;${this.position}: 1rem;right: 1rem;display: flex;flex-flow: column wrap;gap: 1rem;`; + wrapper.appendChild(notification); + + if (this.duration && Number(this.duration) !== 0) { + setTimeout(() => { + notification.remove(); + }, this.duration); + } + } +} + +export default Notification; diff --git a/public/projects/js-small-apps/budget-app/lib/class-transaction.js b/public/projects/js-small-apps/budget-app/lib/class-transaction.js new file mode 100644 index 0000000..6807372 --- /dev/null +++ b/public/projects/js-small-apps/budget-app/lib/class-transaction.js @@ -0,0 +1,76 @@ +/** + * Transaction class + * + * Create a new transaction with id, date, name, type, category and amount. + */ +class Transaction { + #id = 0; + #date = new Date(); + #name = ""; + #type = ""; + #category = 0; + #amount = 0; + + constructor(id, date, name, type, category, amount) { + this.#id = Number(id); + this.#date = new Date(date); + this.#name = name; + this.#type = type; + this.#category = Number(category); + this.#amount = Number.parseFloat(amount); + } + + get id() { + return this.#id; + } + + set date(datetime) { + this.#date = datetime; + } + + get date() { + return this.#date; + } + + set name(string) { + this.#name = string; + } + + get name() { + return this.#name; + } + + set type(string) { + this.#type = string; + } + + get type() { + return this.#type; + } + + set category(string) { + this.#category = string; + } + + get category() { + return this.#category; + } + + set amount(number) { + this.#amount = number; + } + + get amount() { + return this.#amount; + } + + update(date, name, type, category, amount) { + this.date = date; + this.name = name; + this.type = type; + this.category = category; + this.amount = amount; + } +} + +export default Transaction; diff --git a/public/projects/js-small-apps/budget-app/lib/class-user.js b/public/projects/js-small-apps/budget-app/lib/class-user.js new file mode 100644 index 0000000..e0e137b --- /dev/null +++ b/public/projects/js-small-apps/budget-app/lib/class-user.js @@ -0,0 +1,79 @@ +import Budget from "./class-budget.js"; + +class User { + #id = 0; + #username = "Anonymous"; + #firstName = "John"; + #lastName = "Doe"; + #role = "admin"; + #locale = "en-US"; + #accountCreation = new Date(); + #budget = 0; + + constructor(id, username) { + this.#id = id; + this.#username = username; + } + + get id() { + return this.#id; + } + + set username(name) { + this.#username = name; + } + + get username() { + return this.#username; + } + + set firstName(name) { + this.#firstName = name; + } + + get firstName() { + return this.#firstName; + } + + set lastName(name) { + this.#lastName = name; + } + + get lastName() { + return this.#lastName; + } + + set role(string) { + this.#role = string; + } + + get role() { + return this.#role; + } + + set locale(code) { + this.#locale = code; + } + + get locale() { + return this.#locale; + } + + get accountCreation() { + return this.#accountCreation; + } + + set budget(number) { + this.#budget = new Budget(number); + } + + get budget() { + return this.#budget; + } + + name() { + return `${this.#firstName} ${this.#lastName}`; + } +} + +export default User; diff --git a/public/projects/js-small-apps/budget-app/lib/utils/currency.js b/public/projects/js-small-apps/budget-app/lib/utils/currency.js new file mode 100644 index 0000000..04d3ad0 --- /dev/null +++ b/public/projects/js-small-apps/budget-app/lib/utils/currency.js @@ -0,0 +1,47 @@ +/** + * Convert a number to fr_FR locale. + * @param {Number} number A number to format. + * @returns A number formatted with fr_FR locale. + */ +const getCurrencyFR = (number) => { + const formatted = + Number.parseFloat(number) + .toFixed(2) + .replace(".", ",") + .replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1 ") + " €"; + return formatted; +}; + +/** + * Convert a number to en_US locale. + * @param {Number} number A number to format. + * @returns A number formatted with en_US locale. + */ +const getCurrencyUS = (number) => { + const formatted = + "$" + + Number.parseFloat(number) + .toFixed(2) + .replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,"); + return formatted; +}; + +/** + * Get a number formatted based on a locale. + * @param {Number} number A number to format. + * @param {String} format A language code. + * @returns A formatted number. + */ +const getCurrencyFormat = (number, format) => { + switch (format) { + case "fr-FR": + return getCurrencyFR(number); + case "en-US": + return getCurrencyUS(number); + default: + console.log("Not supported!"); + break; + } +}; + +export default getCurrencyFormat; |
