aboutsummaryrefslogtreecommitdiffstats
path: root/public/projects/js-small-apps/budget-app/lib
diff options
context:
space:
mode:
Diffstat (limited to 'public/projects/js-small-apps/budget-app/lib')
-rw-r--r--public/projects/js-small-apps/budget-app/lib/class-budget-app.js144
-rw-r--r--public/projects/js-small-apps/budget-app/lib/class-budget.js44
-rw-r--r--public/projects/js-small-apps/budget-app/lib/class-category.js37
-rw-r--r--public/projects/js-small-apps/budget-app/lib/class-notification.js89
-rw-r--r--public/projects/js-small-apps/budget-app/lib/class-transaction.js76
-rw-r--r--public/projects/js-small-apps/budget-app/lib/class-user.js79
-rw-r--r--public/projects/js-small-apps/budget-app/lib/utils/currency.js47
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;