Kaynağa Gözat

Create the view income page.

Lee Morgan 11 ay önce
ebeveyn
işleme
4853a07b9f

+ 0 - 1
src/views/createHtml.js

@@ -10,7 +10,6 @@ const esbuildProm = esbuild.build({
     entryPoints: [`${import.meta.dirname}/js/index.js`, `${import.meta.dirname}/css/index.css`],
     bundle: true,
     minify: isProduction,
-    sourcemap: isProduction ? false : "inline",
     write: false,
     outdir: import.meta.dirname
 });

+ 2 - 1
src/views/css/index.css

@@ -3,6 +3,7 @@
 @import "./createAllowance.css";
 @import "./viewTransactions.css";
 @import "./transactionDetails.css";
+@import "./viewCategory.css";
 
 :root {
     --primary: #6E4B3A;
@@ -48,7 +49,7 @@ body{
     width: 100%;
     position: relative;
     padding: 10px;
-    padding: 75px 10px 10px 10px;
+    padding: 100px 10px 10px 10px;
 }
 
 .standardForm{

+ 35 - 0
src/views/css/viewCategory.css

@@ -0,0 +1,35 @@
+#ViewIncome,
+#ViewBills,
+#ViewAllowances{
+    display: flex;
+    flex-direction: column;
+    justify-content: flex-start;
+    min-height: 100%;
+}
+
+.categoryContainer{
+    display: flex;
+    flex-direction: column;
+    width: 100%;
+    max-width: 750px;
+}
+
+.viewCategoryItem{
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 5px 15px;
+    margin: 5px 0;
+    background: var(--surface);
+    width: 100%;
+    cursor: pointer;
+    min-height: 55px;
+}
+
+.viewCategoryItem:hover{
+    box-shadow: 0 0 3px var(--secondary);
+}
+
+.categoryItemSpent{
+    font-weight: bold;
+}

+ 0 - 1
src/views/css/viewTransactions.css

@@ -3,7 +3,6 @@
     flex-direction: column;
     justify-content: flex-start;
     min-height: 100%;
-    padding-top: 75px;
 }
 
 #ViewTransactions h1{

+ 5 - 0
src/views/js/Elem.js

@@ -17,6 +17,11 @@ export default class Elem {
         return this;
     }
 
+    addStyle(k, v){
+        this.elem.style[k] = v;
+        return this;
+    }
+
     text(v){
         this.elem.textContent = v;
         return this;

+ 14 - 0
src/views/js/data/Account.js

@@ -35,6 +35,10 @@ export default class Account{
         return this._transactions;
     }
 
+    get income(){
+        return this._income;
+    }
+
     get isPopulated(){
         return this._populated;
     }
@@ -58,6 +62,16 @@ export default class Account{
         }
     }
 
+    categorySpent(category){
+        let total = 0;
+        for(let i = 0; i < this._transactions.length; i++){
+            if(this._transactions[i].categoryId === category.id){
+                total += this._transactions[i].rawAmount;
+            }
+        }
+        return Format.centsToDollars(total);
+    }
+
     incomeTotal(){
         let income = 0;
         for(let i = 0; i < this._income.length; i++){

+ 3 - 1
src/views/js/data/Income.js

@@ -1,3 +1,5 @@
+import Format from "../Format.js";
+
 export default class Income{
     constructor(id, name, amount){
         this._id = id;
@@ -14,7 +16,7 @@ export default class Income{
     }
 
     get amount(){
-        return this._amount;
+        return Format.centsToDollars(this._amount);
     }
 
     get type(){

+ 8 - 0
src/views/js/data/Transaction.js

@@ -42,6 +42,10 @@ export default class Transaction{
         }
     }
 
+    get categoryId(){
+        return this._categoryId;
+    }
+
     get rawCategory(){
         return this._category;
     }
@@ -58,6 +62,10 @@ export default class Transaction{
         return Format.centsToDollars(this._amount);
     }
 
+    get rawAmount(){
+        return this._amount;
+    }
+
     set amount(v){
         if(typeof v !== "number") v = Number(v);
         this._amount = Format.dollarsToCents(v);

+ 2 - 0
src/views/js/index.js

@@ -14,6 +14,7 @@ import ViewMenu from "./pages/ViewMenu.js";
 import ViewTransactions from "./pages/ViewTransactions.js";
 import TransactionDetails from "./pages/TransactionDetails.js";
 import EditTransaction from "./pages/EditTransaction.js";
+import ViewIncome from "./pages/ViewIncome.js";
 
 const pages = document.querySelector(".page");
 let currentPage;
@@ -36,6 +37,7 @@ window.changePage = (page, data)=>{
         case "viewTransactions": currentPage = new ViewTransactions(); break;
         case "transactionDetails": currentPage = new TransactionDetails(data); break;
         case "editTransaction": currentPage = new EditTransaction(data); break;
+        case "viewIncome": currentPage = new ViewIncome(); break;
     }
     console.timeEnd("change page");
 }

+ 67 - 0
src/views/js/pages/ViewIncome.js

@@ -0,0 +1,67 @@
+import Page from "./Page.js";
+import Elem from "../Elem.js";
+import Format from "../Format.js";
+
+export default class ViewIncome extends Page{
+    constructor(){
+        super("ViewIncome", ["home", "back-viewMenu", "logout"]);
+
+        this.render();
+    }
+
+    generateColor(spent, amount){
+        if(amount <= 0) return "hsl(0, 100%, 50%)";
+
+        const percent = Math.min(spent / amount, 1); 
+        let hue;
+        if(percent < 0.5){
+            hue = percent / 0.5 * 45;
+        }else{
+            hue = 45 + (percent - 0.5) / 0.5 * (120 -45);
+        }
+
+        const saturation = 65 - percent * 15;
+        const lightness = 28 + (1 - Math.abs(percent - 0.5) * 2) * 10;
+
+        return `hsl(${hue}, ${saturation}%, ${lightness}%)`;
+    }
+
+    render(){
+        new Elem("h1")
+            .text(`${user.account.name} income`)
+            .appendTo(this.container);
+
+        const incomeContainer = new Elem("div")
+            .addClass("categoryContainer")
+            .appendTo(this.container);
+
+        const income = user.account.income;
+        for(let i = 0; i < income.length; i++){
+            const spent = user.account.categorySpent(income[i]);
+            const spentAsCurrency = Format.currency(user.account.categorySpent(income[i]));
+            const amount = income[i].amount;
+            const amountAsCurrency = Format.currency(income[i].amount);
+
+            new Elem("div")
+                .addClass("viewCategoryItem")
+                .append(new Elem("p")
+                    .text(income[i].name)
+                )
+                .append(new Elem("p")
+                    .addClass("categoryItemSpent")
+                    .append(new Elem("span")
+                        .text(spentAsCurrency)
+                        .addStyle("color", this.generateColor(spent, amount))
+                    )
+                    .append(new Elem("span")
+                        .text(" / ")
+                    )
+                    .append(new Elem("span")
+                        .text(amountAsCurrency)
+                        .addStyle("color", "hsl(120, 50%, 28%)")
+                    )
+                )
+                .appendTo(incomeContainer);
+        }
+    }
+}

+ 6 - 0
src/views/js/pages/ViewMenu.js

@@ -15,5 +15,11 @@ export default class ViewMenu extends Page{
             .onclick(()=>{changePage("viewTransactions")})
             .focus()
             .appendTo(this.container);
+
+        new Elem("button")
+            .text("Income")
+            .addClass("button")
+            .onclick(()=>{changePage("viewIncome")})
+            .appendTo(this.container);
     }
 }