From 48fc5a2eecfcb24ddf729b8f6791579bc7ac73b9 Mon Sep 17 00:00:00 2001
From: Robert Goldmann <deadlocker@gmx.de>
Date: Sat, 21 Apr 2018 15:42:22 +0200
Subject: [PATCH] #297 - accounts can now be created, updated and deleted

---
 .../controller/AccountController.java         | 74 +++++++++++++++++++
 .../controller/CategoryController.java        |  2 +-
 .../controller/EmptyPageController.java       |  7 --
 .../budgetmaster/services/AccountService.java | 38 ++++++++++
 .../budgetmaster/utils/Strings.java           |  4 +
 .../validators/AccountValidator.java          | 21 ++++++
 src/main/resources/languages/_de.properties   |  9 +++
 src/main/resources/languages/_en.properties   | 29 +++++---
 .../resources/templates/accounts/accounts.ftl | 57 ++++++++++++++
 .../templates/accounts/newAccount.ftl         | 68 +++++++++++++++++
 10 files changed, 291 insertions(+), 18 deletions(-)
 create mode 100644 src/main/java/de/deadlocker8/budgetmaster/services/AccountService.java
 create mode 100644 src/main/java/de/deadlocker8/budgetmaster/validators/AccountValidator.java
 create mode 100644 src/main/resources/templates/accounts/accounts.ftl
 create mode 100644 src/main/resources/templates/accounts/newAccount.ftl

diff --git a/src/main/java/de/deadlocker8/budgetmaster/controller/AccountController.java b/src/main/java/de/deadlocker8/budgetmaster/controller/AccountController.java
index adf916014..f6825fc36 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/controller/AccountController.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/controller/AccountController.java
@@ -2,10 +2,17 @@ package de.deadlocker8.budgetmaster.controller;
 
 import de.deadlocker8.budgetmaster.entities.Account;
 import de.deadlocker8.budgetmaster.repositories.AccountRepository;
+import de.deadlocker8.budgetmaster.services.AccountService;
+import de.deadlocker8.budgetmaster.utils.ResourceNotFoundException;
+import de.deadlocker8.budgetmaster.validators.AccountValidator;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.ModelAttribute;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
 
 import javax.servlet.http.HttpServletRequest;
 import java.util.List;
@@ -17,6 +24,9 @@ public class AccountController extends BaseController
 	@Autowired
 	private AccountRepository accountRepository;
 
+	@Autowired
+	private AccountService accountService;
+
 	@RequestMapping(value = "/account/{ID}/select")
 	public String selectAccount(HttpServletRequest request, @PathVariable("ID") Integer ID)
 	{
@@ -33,4 +43,68 @@ public class AccountController extends BaseController
 
 		return "redirect:" + request.getHeader("Referer");
 	}
+
+	@RequestMapping("/accounts")
+	public String accounts(Model model)
+	{
+		model.addAttribute("accounts", accountRepository.findAllByOrderByNameAsc());
+		return "accounts/accounts";
+	}
+
+	@RequestMapping("/accounts/{ID}/requestDelete")
+	public String requestDeleteAccount(Model model, @PathVariable("ID") Integer ID)
+	{
+		model.addAttribute("accounts", accountRepository.findAllByOrderByNameAsc());
+		model.addAttribute("currentAccount", accountRepository.getOne(ID));
+		return "accounts/accounts";
+	}
+
+	@RequestMapping("/accounts/{ID}/delete")
+	public String deleteAccountAndReferringPayments(Model model, @PathVariable("ID") Integer ID)
+	{
+		accountService.deleteAccount(ID);
+
+		return "redirect:/accounts";
+	}
+
+	@RequestMapping("/accounts/newAccount")
+	public String newAccount(Model model)
+	{
+		Account emptyAccount = new Account();
+		model.addAttribute("account", emptyAccount);
+		return "accounts/newAccount";
+	}
+
+	@RequestMapping("/accounts/{ID}/edit")
+	public String editAccount(Model model, @PathVariable("ID") Integer ID)
+	{
+		Account account = accountRepository.findOne(ID);
+		if(account == null)
+		{
+			throw new ResourceNotFoundException();
+		}
+
+		model.addAttribute("account", account);
+		return "accounts/newAccount";
+	}
+
+	@RequestMapping(value = "/accounts/newAccount", method = RequestMethod.POST)
+	public String post(Model model, @ModelAttribute("NewAccount") Account account, BindingResult bindingResult)
+	{
+		AccountValidator accountValidator = new AccountValidator();
+		accountValidator.validate(account, bindingResult);
+
+		if(bindingResult.hasErrors())
+		{
+			model.addAttribute("error", bindingResult);
+			model.addAttribute("account", account);
+			return "accounts/newAccount";
+		}
+		else
+		{
+			accountRepository.save(account);
+		}
+
+		return "redirect:/accounts";
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/de/deadlocker8/budgetmaster/controller/CategoryController.java b/src/main/java/de/deadlocker8/budgetmaster/controller/CategoryController.java
index 5079ecabb..32a11a087 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/controller/CategoryController.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/controller/CategoryController.java
@@ -32,7 +32,7 @@ public class CategoryController extends BaseController
 	private HelpersService helpers;
 
 	@RequestMapping("/categories")
-	public String index(Model model)
+	public String categories(Model model)
 	{
 		model.addAttribute("categories", categoryRepository.findAllByOrderByNameAsc());
 		return "categories/categories";
diff --git a/src/main/java/de/deadlocker8/budgetmaster/controller/EmptyPageController.java b/src/main/java/de/deadlocker8/budgetmaster/controller/EmptyPageController.java
index 178217dee..da1b03012 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/controller/EmptyPageController.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/controller/EmptyPageController.java
@@ -8,13 +8,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
 @Controller
 public class EmptyPageController extends BaseController
 {
-	@RequestMapping("/accounts")
-	public String accounts(Model model)
-	{
-		model.addAttribute("active", "accounts");
-		return "emptyPage";
-	}
-
 	@RequestMapping("/reports")
 	public String reports(Model model)
 	{
diff --git a/src/main/java/de/deadlocker8/budgetmaster/services/AccountService.java b/src/main/java/de/deadlocker8/budgetmaster/services/AccountService.java
new file mode 100644
index 000000000..80cac1942
--- /dev/null
+++ b/src/main/java/de/deadlocker8/budgetmaster/services/AccountService.java
@@ -0,0 +1,38 @@
+package de.deadlocker8.budgetmaster.services;
+
+import de.deadlocker8.budgetmaster.entities.Account;
+import de.deadlocker8.budgetmaster.repositories.AccountRepository;
+import de.deadlocker8.budgetmaster.repositories.PaymentRepository;
+import de.deadlocker8.budgetmaster.utils.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AccountService
+{
+	private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
+	private AccountRepository accountRepository;
+	private PaymentRepository paymentRepository;
+
+	@Autowired
+	public AccountService(AccountRepository accountRepository, PaymentRepository paymentRepository)
+	{
+		this.accountRepository = accountRepository;
+		this.paymentRepository = paymentRepository;
+
+		if(accountRepository.findAll().size() == 0)
+		{
+			accountRepository.save(new Account(Strings.ACCOUNT_DEFAULT_NAME));
+			LOGGER.debug("Created default category NONE");
+		}
+	}
+
+	public void deleteAccount(int ID)
+	{
+		Account accountToDelete = accountRepository.findOne(ID);
+		paymentRepository.delete(accountToDelete.getReferringPayments());
+		accountRepository.delete(ID);
+	}
+}
diff --git a/src/main/java/de/deadlocker8/budgetmaster/utils/Strings.java b/src/main/java/de/deadlocker8/budgetmaster/utils/Strings.java
index 9e3dea2fc..470cdfb19 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/utils/Strings.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/utils/Strings.java
@@ -107,6 +107,9 @@ public class Strings
     public static final String REPORT_PAYMENTS = "report.payments";
     public static final String REPORT_BUDGET_REST = "report.budget.rest";
 
+    //ACCOUNT
+    public static final String ACCOUNT_DEFAULT_NAME = "account.default.name";
+
     //WEEK_DAYS
     public static final String MONDAY ="monday";
     public static final String TUESDAY ="tuesday";
@@ -192,6 +195,7 @@ public class Strings
     public static final String WARNING_INTEGER_HEIGHT_IN_PIXELS = "warning.integer.height.in.pixels";
     public static final String WARNING_EMPTY_SAVEPATH_CHART = "warning.empty.savepath.chart";
     public static final String WARNING_EMPTY_CATEGORY_NAME = "warning.empty.category.name";
+    public static final String WARNING_EMPTY_ACCOUNT_NAME = "warning.empty.account.name";
     public static final String WARNING_EMPTY_CATEGORY_COLOR = "warning.empty.category.color";
     public static final String WARNING_EMPTY_PAYMENT_NAME = "warning.empty.payment.name";
     public static final String WARNING_NAME_CHARACTER_LIMIT_REACHED_45 = "warning.name.character.limit.reached.45";
diff --git a/src/main/java/de/deadlocker8/budgetmaster/validators/AccountValidator.java b/src/main/java/de/deadlocker8/budgetmaster/validators/AccountValidator.java
new file mode 100644
index 000000000..0cff68a91
--- /dev/null
+++ b/src/main/java/de/deadlocker8/budgetmaster/validators/AccountValidator.java
@@ -0,0 +1,21 @@
+package de.deadlocker8.budgetmaster.validators;
+
+import de.deadlocker8.budgetmaster.entities.Category;
+import de.deadlocker8.budgetmaster.utils.Strings;
+import org.springframework.validation.Errors;
+import org.springframework.validation.ValidationUtils;
+import org.springframework.validation.Validator;
+
+
+public class AccountValidator implements Validator
+{
+	public boolean supports(Class clazz)
+	{
+		return Category.class.equals(clazz);
+	}
+
+	public void validate(Object obj, Errors errors)
+	{
+		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", Strings.WARNING_EMPTY_ACCOUNT_NAME);
+	}
+}
\ No newline at end of file
diff --git a/src/main/resources/languages/_de.properties b/src/main/resources/languages/_de.properties
index 26afbed66..995eb3513 100644
--- a/src/main/resources/languages/_de.properties
+++ b/src/main/resources/languages/_de.properties
@@ -43,6 +43,8 @@ title.database.import=Datenbank importieren
 title.datepicker=Datum w�hlen
 title.tags=Das Tag-Eingabefeld
 title.account=Konto
+title.account.new=Neues Konto
+title.account.edit=Konto bearbeiten
 
 # LOAD
 load.charts=Lade Diagramme...
@@ -145,6 +147,9 @@ notification.no.update.available=Kein Update verf
 # INFO
 info.title.category.delete=Kategorie l�schen
 info.text.category.delete=M�chtest du die Kategorie "{0}" wirklich unwiderruflich l�schen?
+info.title.account.delete=Konto l�schen
+info.text.account.delete=M�chtest du das Konto "{0}" wirklich unwiderruflich l�schen?<br>Hinweis: Diesem Konto sind {1} Buchungen zugeordnet. Beim L�schen des Kontos werden diese ebenfalls gel�scht!
+info.button.account.delete=Konto un Buchungen l�schen
 info.title.payment.delete=Buchung l�schen
 info.text.payment.delete=M�chtest du die Buchung "{0}" wirklich unwiderruflich l�schen?
 info.text.payment.repeating.delete=Es handelt sich um eine wiederkehrende Zahlung. Welche Zahlungen sollen gel�scht werden?
@@ -198,6 +203,7 @@ warning.empty.height.in.pixels=Bitte gib eine H
 warning.integer.height.in.pixels=Nur ganzahlige Werte sind f�r das Feld H�he erlaubt.
 warning.empty.savepath.chart=W�hle einen Speicherort f�r das Diagramm aus.
 warning.empty.category.name=Bitte gib einen Namen ein.
+warning.empty.account.name=Bitte gib einen Namen ein.
 warning.empty.category.color=Die Kategoriefarbe darf nicht leer sein.
 warning.empty.payment.name=Das Feld f�r den Namen darf nicht leer sein.
 warning.name.character.limit.reached.45=Der Name darf maximal 45 Zeichen lang sein.
@@ -304,6 +310,9 @@ menu.accounts=Konten
 
 category.new.label.name=Name
 
+account.new.label.name=Name
+account.default.name=Standardkonto
+
 payment.new.label.name=Name
 payment.new.label.amount=Betrag
 payment.new.label.category=Kategorie
diff --git a/src/main/resources/languages/_en.properties b/src/main/resources/languages/_en.properties
index e49c5c03d..5963c3101 100644
--- a/src/main/resources/languages/_en.properties
+++ b/src/main/resources/languages/_en.properties
@@ -13,8 +13,8 @@ github.url=https://github.com/deadlocker8/BudgetMaster
 # ERRORPAGES
 errorpages.home=To Homepage
 errorpages.403=Access denied.
-errorpages.404=The requested page doesn't exist.
-errorpages.418=I'm a teapot.
+errorpages.404=The requested page doesn''t exist.
+errorpages.418=I''m a teapot.
 errorpages.418.credits=Teapot icon made by <a href="http://www.freepik.com" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
 errorpages.500=An internal server error occurred.
 
@@ -43,6 +43,8 @@ title.database.import=Import Database
 title.datepicker=Choose date
 title.tags=The Tag-Inputfield
 title.account=Account
+title.account.new=New Account
+title.account.edit=Edit Account
 
 # LOAD
 load.charts=Loading Charts...
@@ -82,7 +84,7 @@ undefined=undefined
 tagfield.placeholder=Enter Tag here
 shortcut.dev.console=F12
 local.server.status.ok=Server is running.
-local.server.status.not.started=Server couldn't be started.
+local.server.status.not.started=Server couldn''t be started.
 local.server.action.not.started=Start
 local.server.status.not.present=Server not found.
 local.server.action.not.present=Download
@@ -144,9 +146,12 @@ notification.no.update.available=No update available.
 
 # INFO
 info.title.category.delete=Delete Category
-info.text.category.delete=Do you really want to delete the category "{0}"? This can't be undone.
+info.text.category.delete=Do you really want to delete the category "{0}"? This can''t be undone.
+info.title.account.delete=Delete Account
+info.text.account.delete=Do you really want to delete the account "{0}"? This can''t be undone.<br>Note: There are {1} payments associated with this account. Deleting this account will delete all releated payments too!
+info.button.account.delete=Delete Account and Payments
 info.title.payment.delete=Delete Entry
-info.text.payment.delete=Do you really want to delete the entry "{0}"? This can't be undone.
+info.text.payment.delete=Do you really want to delete the entry "{0}"? This can''t be undone.
 info.text.payment.repeating.delete=The entry you want to delete is a repeating entry. What entries should be deleted?
 info.text.payment.repeating.delete.all=All Entries
 info.text.payment.repeating.delete.futures=Future Entries
@@ -168,7 +173,7 @@ info.text.database.import.dialog=Do you want to delete the database before impor
 info.text.database.import.dialog.delete=Yes, delete database
 info.text.database.import.dialog.append=No, append data
 info.title.database.delete=Delete Database
-info.header.text.database.delete=Do you really want to delete this entry? This can't be undone.
+info.header.text.database.delete=Do you really want to delete this entry? This can''t be undone.
 info.text.database.delete=Please enter the following code for verification:\t{0}
 info.title.welcome=Welcome
 info.header.text.welcome=Welcome to BudgetMaster
@@ -185,7 +190,7 @@ info.text.update.available.show.changes.detailed=(detailed information on GitHub
 info.text.update.available.now=Update Now
 info.title.start.after.update=Update successful
 info.header.text.start.after.update=Successfully updated BudgetMaster to version {0}
-info.text.start.after.update=Note: You have to update the BudgetMasterServer manually, if it's no local server!
+info.text.start.after.update=Note: You have to update the BudgetMasterServer manually, if it''s no local server!
 info.tags=Suggestions based on already used tags will show up once you start typing.\n\nEnter - Appends the current input field content as a new tag.\nArrow Down - Opens the suggestions if the input field is empty.
 info.title.shutdown=Shutdown BudgetMaster
 info.text.shutdown=Do you really want to shutdown BudgetMaster? This could lead to unforeseen consequences during running tasks.
@@ -198,6 +203,7 @@ warning.empty.height.in.pixels=Please enter a height in pixels.
 warning.integer.height.in.pixels=Only integer values are allowed for the height field.
 warning.empty.savepath.chart=Please select a location where you want to save the chart.
 warning.empty.category.name=Please insert a name.
+warning.empty.account.name=Please insert a name.
 warning.empty.category.color=The category color should not be empty.
 warning.empty.payment.name=The field for the name can not be empty.
 warning.name.character.limit.reached.45=The name must not exceed 45 characters in length.
@@ -229,9 +235,9 @@ error.500=An internal server error occurred while processing the request.
 error.create.ui=An error occurred while creating the user interface.
 error.server.connection=An error occurred while connecting to the server. Please check your settings.
 error.server.connection.with.details=An error occurred while connecting to the server. Please check your settings.\n\nError details:\n{0}
-error.open.folder=The folder couldn't be opened.\n\n{0}
-error.open.chart=The chart couldn't be opened.\n\n{0}
-error.open.report=The report couldn't be opened.\n\n{0}
+error.open.folder=The folder couldn''t be opened.\n\n{0}
+error.open.chart=The chart couldn''t be opened.\n\n{0}
+error.open.report=The report couldn''t be opened.\n\n{0}
 error.chart.export=An error occurred while exporting the chart:\n\n{0}
 error.report.save=An error occurred while creating the month report:\n\n{0}
 error.settings.save=An error occurred while saving the settings.
@@ -304,6 +310,9 @@ menu.accounts=Accounts
 
 category.new.label.name=Name
 
+account.new.label.name=Name
+account.default.name=Default Account
+
 payment.new.label.name=Name
 payment.new.label.amount=Amount
 payment.new.label.category=Category
diff --git a/src/main/resources/templates/accounts/accounts.ftl b/src/main/resources/templates/accounts/accounts.ftl
new file mode 100644
index 000000000..dc63922b2
--- /dev/null
+++ b/src/main/resources/templates/accounts/accounts.ftl
@@ -0,0 +1,57 @@
+<html>
+    <head>
+        <#import "../header.ftl" as header>
+        <@header.header/>
+        <#assign locale = static["tools.Localization"]>
+    </head>
+    <body class="budgetmaster-blue-light">
+        <#import "../navbar.ftl" as navbar>
+        <@navbar.navbar "accounts"/>
+
+        <main>
+            <div class="card main-card">
+                <div class="container">
+                    <div class="section center-align">
+                        <div class="grey-text text-darken-4 headline">${locale.getString("menu.accounts")}</div>
+                    </div>
+                </div>
+                <br>
+                <div class="center-align"><a href="/accounts/newAccount" class="waves-effect waves-light btn budgetmaster-blue"><i class="material-icons left">add</i>${locale.getString("title.account.new")}</a></div>
+                <br>
+                <div class="container">
+                    <table class="bordered">
+                        <#list accounts as account>
+                        <tr>
+                            <td>${account.getName()}</td>
+                            <td>
+                                <a href="/accounts/${account.getID()}/edit" class="btn-flat no-padding"><i class="material-icons left">edit</i></a>
+                                <a href="/accounts/${account.getID()}/requestDelete" class="btn-flat no-padding"><i class="material-icons left">delete</i></a>
+                            </td>
+                        </tr>
+                        </#list>
+                    </table>
+                </div>
+            </div>
+
+            <#if currentAccount??>
+                <!-- confirm delete modal -->
+                <div id="modalConfirmDelete" class="modal">
+                    <div class="modal-content">
+                        <h4>${locale.getString("info.title.account.delete")}</h4>
+                        <p>${locale.getString("info.text.account.delete", currentAccount.getName(), currentAccount.getReferringPayments()?size)}</p>
+                    </div>
+                    <div class="modal-footer">
+                        <a href="/accounts" class="modal-action modal-close waves-effect waves-red btn-flat ">${locale.getString("cancel")}</a>
+                        <a href="/accounts/${currentAccount.getID()}/delete" class="modal-action modal-close waves-effect waves-green btn-flat ">${locale.getString("info.button.account.delete")}</a>
+                    </div>
+                </div>
+            </#if>
+        </main>
+
+        <!--  Scripts-->
+        <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
+        <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
+        <script src="/js/main.js"></script>
+        <script src="/js/categories.js"></script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/src/main/resources/templates/accounts/newAccount.ftl b/src/main/resources/templates/accounts/newAccount.ftl
new file mode 100644
index 000000000..a34bdbe00
--- /dev/null
+++ b/src/main/resources/templates/accounts/newAccount.ftl
@@ -0,0 +1,68 @@
+<html>
+    <head>
+        <#import "../header.ftl" as header>
+        <@header.header/>
+        <#assign locale = static["tools.Localization"]>
+    </head>
+    <body class="budgetmaster-blue-light">
+        <#import "../navbar.ftl" as navbar>
+        <@navbar.navbar "accounts"/>
+
+        <main>
+            <div class="card main-card">
+                <div class="container">
+                    <div class="section center-align">
+                        <div class="grey-text text-darken-4 headline"><#if account.getID()??>${locale.getString("title.account.edit")}<#else>${locale.getString("title.account.new")}</#if></div>
+                    </div>
+                </div>
+                <div class="container">
+                    <#import "../validation.ftl" as validation>
+                    <form name="NewAccount" action="/accounts/newAccount" method="post">
+                        <input type="hidden" name="ID" value="<#if account.getID()??>${account.getID()}</#if>">
+
+                        <#-- name -->
+                        <div class="row">
+                            <div class="input-field col s12 m12 l8 offset-l2">
+                                <input id="account-name" type="text" name="name" <@validation.validation "name"/> value="<#if account.getName()??>${account.getName()}</#if>">
+                                <label for="account-name">${locale.getString("account.new.label.name")}</label>
+                            </div>
+                        </div>
+                        <br>
+
+                        <#-- buttons -->
+                        <div class="row hide-on-small-only">
+                            <div class="col m6 l4 offset-l2 right-align">
+                                <a href="/accounts" class="waves-effect waves-light btn budgetmaster-blue"><i class="material-icons left">clear</i>${locale.getString("cancel")}</a>
+                            </div>
+
+                            <div class="col m6 l4 left-align">
+                                <button class="btn waves-effect waves-light budgetmaster-blue" type="submit" name="action">
+                                    <i class="material-icons left">save</i>${locale.getString("save")}
+                                </button>
+                            </div>
+                        </div>
+                        <div class="hide-on-med-and-up">
+                            <div class="row center-align">
+                                <div class="col s12">
+                                    <a href="/accounts" class="waves-effect waves-light btn budgetmaster-blue"><i class="material-icons left">clear</i>${locale.getString("cancel")}</a>
+                                </div>
+                            </div>
+                            <div class="row center-align">
+                                <div class="col s12">
+                                    <button class="btn waves-effect waves-light budgetmaster-blue" type="submit" name="buttonSave">
+                                        <i class="material-icons left">save</i>${locale.getString("save")}
+                                    </button>
+                                </div>
+                            </div>
+                        </div>
+                    </form>
+                </div>
+            </div>
+        </main>
+
+        <!-- Scripts-->
+        <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
+        <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
+        <script src="/js/main.js"></script>
+    </body>
+</html>
\ No newline at end of file
-- 
GitLab