Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0ba913257 | ||
|
|
33fa0b4a89 | ||
|
|
19b340b004 | ||
|
|
cc178edb1e
|
||
|
|
dac0f6ecc2 | ||
|
|
46d6d2e036 | ||
|
|
38074fdc36 | ||
|
|
b11d5ceca3 | ||
|
|
ed8b2b47b6 | ||
|
|
3f8dbef6ad
|
||
|
|
0b9a90fabe
|
||
|
|
5afdd6a8d0 | ||
|
|
f409602e22 | ||
|
|
7d26825c63 | ||
|
|
b346ee6222 | ||
|
|
343a4f8275 | ||
|
|
0129315523 | ||
|
|
f498386f96 | ||
|
|
b3b06226ee | ||
|
|
d82bfd5b56
|
||
|
|
a7bb955c8a | ||
|
|
19081e3bd3
|
||
|
|
7269814501
|
||
|
|
16f267bcd4 | ||
|
|
8998283552 | ||
|
|
5b6ce3b09d | ||
|
|
e45b7ca946
|
||
|
|
c0e2d01ea6
|
||
|
|
3d55a2b0d0 | ||
|
|
ec309fbafd | ||
|
|
c1adb31657 | ||
|
|
05fa5558e3 | ||
|
|
d2e69f230f | ||
|
|
0672981e69 | ||
|
|
d6425043cf
|
||
|
|
cf3d3738f1
|
||
|
|
cc6fd937db | ||
|
|
7c34094a93 |
No files matched your search
@@ -1,27 +1,43 @@
|
|||||||
# Retirement Calculator
|
# Retirement Calculator
|
||||||
## 2800-202510-BBY14
|
### 2800-202510-BBY14
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
Retirement Calculator - The goal of the application is to help users manage and track their financial progress in a way that reflects real life. Instead of just acting as a calculator, the app functions as a dynamic tracker. It shows the user a percentage of how much of their goal has been achieved and compares their actual performance to their planned targets.
|
RCalculator is a dynamic financial tracking application designed to help users manage and monitor their progress towards long-term financial goals, particularly retirement. It moves beyond simple calculations by providing personalized insights, tracking actual performance against planned targets, and offering a clear view of your financial journey towards achieving your desired future.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Do calculator stuff
|
- **Personalized Financial Profile:** Users complete a comprehensive questionnaire to build a financial profile, enabling tailored guidance and projections.
|
||||||
|
- **Comprehensive Asset Management:** Add, track, and manage various types of assets including savings, stocks, real estate, and other investments for a holistic view of net worth.
|
||||||
|
- **Strategic Goal Planning:** Define long-term financial objectives (e.g., retirement, home purchase, education) and create detailed plans with actionable steps.
|
||||||
|
- **Clear Financial Projections:** Visualize potential investment growth and assess the feasibility of financial plans through easy-to-understand projections and charts.
|
||||||
|
- **User-Friendly Dashboard:** An intuitive dashboard provides an at-a-glance overview of financial health, asset allocation, and progress towards goals.
|
||||||
|
- **Secure User Authentication:** Robust authentication system to protect sensitive financial data, including secure registration and login processes.
|
||||||
|
- **Dynamic Currency Conversion:** (If applicable) Utilizes geolocation to provide relevant currency information and conversion rates for international users or assets.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Technologies Used
|
## Technologies Used
|
||||||
|
|
||||||
Example:
|
- **Frontend:** EJS (Embedded JavaScript templates), Tailwind CSS, Vanilla JavaScript
|
||||||
- **Frontend**: HTML, CSS, JavaScript
|
- **Backend:** Node.js, Express.js
|
||||||
- **Backend**: Express.js
|
- **Database:** MongoDB
|
||||||
- **Database**: MongoDB
|
- **Authentication:** express-session for session management, bcrypt for password hashing.
|
||||||
|
- **Data Validation:** Joi for schema validation.
|
||||||
|
- **APIs:** Google Gemini API for generating financial advice. **Geolocation API** for currency conversion.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
1. You'll need to setup an instance of MongoDB. You can use the cloud platform, MongoDB Atlas, or create your own instance locally.
|
||||||
|
i. [Create your MongoDB Altas instance.](https://www.mongodb.com/docs/manual/tutorial/getting-started/)
|
||||||
|
ii. [Create your local MongoDB server instance.](https://www.mongodb.com/docs/manual/administration/install-community/)
|
||||||
|
|
||||||
|
After this, you'll need to get your MongoURI from your database instance, as well as your database name for later configuration in the `.env` file.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
1. **Clone the repository:**
|
1. **Clone the repository:**
|
||||||
@@ -47,32 +63,30 @@ Example:
|
|||||||
The application should now be running, typically on `http://localhost:3000` (or the port specified in your `.env` file).
|
The application should now be running, typically on `http://localhost:3000` (or the port specified in your `.env` file).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
retirementCalculator/
|
retirementCalculator/
|
||||||
├── src/
|
├── src/
|
||||||
| ├── auth/
|
│ ├── auth/ # Authentication logic (e.g., passport setup, strategies)
|
||||||
| ├── database/
|
│ ├── database/ # MongoDB connection, schemas, models
|
||||||
│ ├── public/
|
│ ├── public/ # Static assets
|
||||||
│ │ ├── images/
|
│ │ ├── images/ # Site images and icons
|
||||||
│ │ ├── scripts/
|
│ │ ├── scripts/ # Client-side JavaScript files
|
||||||
│ │ └── svgs/
|
│ │ └── svgs/ # SVG icons
|
||||||
| |
|
│ ├── router/ # Express route definitions
|
||||||
│ ├── router/
|
│ ├── util/ # Utility functions (e.g., calculations, helpers)
|
||||||
│ ├── utils/
|
│ └── views/ # EJS templates
|
||||||
│ └── views/
|
│ └── partials/ # Reusable EJS partials (headers, footers, nav)
|
||||||
│ └── partials/
|
|
||||||
│
|
│
|
||||||
├── .env.example
|
├── .env.example # Example environment variables file
|
||||||
├── .gitignore
|
├── .gitignore # Specifies intentionally untracked files that Git should ignore
|
||||||
├── app.js
|
├── app.js # Main application entry point
|
||||||
├── CONTRIBUTING.md
|
├── CONTRIBUTING.md # Guidelines for contributing to the project
|
||||||
├── LICENSE
|
├── LICENSE # Project license information
|
||||||
├── package-lock.json
|
├── package-lock.json # Records exact versions of dependencies
|
||||||
├── package.json
|
├── package.json # Project metadata and dependencies
|
||||||
└── README.md
|
└── README.md # This file
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -84,16 +98,22 @@ retirementCalculator/
|
|||||||
- **[Mitchell Schaeffer](https://github.com/knighthawk4227)** - BCIT CST Student with a passion for technology.
|
- **[Mitchell Schaeffer](https://github.com/knighthawk4227)** - BCIT CST Student with a passion for technology.
|
||||||
|
|
||||||
---
|
---
|
||||||
## more details to come...
|
|
||||||
|
|
||||||
## Limitations and Future Work
|
## Limitations and Future Work
|
||||||
|
|
||||||
### Limitations
|
### Limitations
|
||||||
|
|
||||||
- None
|
- **Generalized Advice:** The application provides financial guidance based on user input and common models; it does not substitute professional financial advisory services.
|
||||||
|
- **Market Volatility:** Projections are based on assumed rates of return and do not account for all potential market fluctuations or unforeseen economic events.
|
||||||
|
- **Manual Data Entry:** Asset information and updates currently require manual input.
|
||||||
|
- **Single User Focus:** Primarily designed for individual financial planning.
|
||||||
|
|
||||||
### Future Work
|
### Future Work
|
||||||
|
|
||||||
- All work
|
- **Third-Party API Integrations:** Connect with financial institutions (e.g., Plaid) for automated asset tracking and transaction importing.
|
||||||
|
- **Advanced Reporting:** Implement more detailed financial reports, customizable charts, and data export options (e.g., PDF, CSV).
|
||||||
|
- **Enhanced Security Features:** Implement Two-Factor Authentication (2FA) and advanced security audits.
|
||||||
|
- **Educational Resources:** Integrate a section with articles, tips, and resources on financial literacy and planning.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ module.exports = (users) => {
|
|||||||
router.post("/signup", async (req, res) => {
|
router.post("/signup", async (req, res) => {
|
||||||
const userSchema = joi.object({
|
const userSchema = joi.object({
|
||||||
email: joi.string().email({ minDomainSegments: 2, tlds: { allow: true } }).required(),
|
email: joi.string().email({ minDomainSegments: 2, tlds: { allow: true } }).required(),
|
||||||
name: joi.string().pattern(new RegExp('^[a-zA-Z]+$')).max(20).required(),
|
name: joi.string().pattern(new RegExp('^[a-zA-Z0-9_ ]*$')).max(20).required(),
|
||||||
password: joi.string().max(20).min(8).required(),
|
password: joi.string().max(20).min(8).required(),
|
||||||
repassword: joi.string().max(20).min(8).required(),
|
repassword: joi.string().max(20).min(8).required(),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ module.exports = (users) => {
|
|||||||
$set: { resetToken: token, resetTokenExpires: expiration }
|
$set: { resetToken: token, resetTokenExpires: expiration }
|
||||||
});
|
});
|
||||||
|
|
||||||
const resetUrl = `http://localhost:${PORT}/reset/${token}`;
|
const resetUrl = `https://rcalculator.sowinski.dev/reset/${token}`;
|
||||||
|
|
||||||
const mailSend = {
|
const mailSend = {
|
||||||
from: process.env.EMAIL_USER,
|
from: process.env.EMAIL_USER,
|
||||||
|
|||||||
@@ -150,6 +150,41 @@ function selectIcon(selectedIcon, assetId="") {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* selectFilter to filter assets by type
|
||||||
|
* @param {button elemenbt} filter
|
||||||
|
*/
|
||||||
|
function selectFilter(filter) {
|
||||||
|
const types = ["other", "saving", "stock"];
|
||||||
|
|
||||||
|
console.log(filter.value);
|
||||||
|
|
||||||
|
types.forEach((type) => {
|
||||||
|
if (filter.value == "all") {
|
||||||
|
document.querySelectorAll(`.${type}-asset`).forEach((preview) => {
|
||||||
|
preview.style.display = "block";
|
||||||
|
});
|
||||||
|
} else if (type != filter.value) {
|
||||||
|
document.querySelectorAll(`.${type}-asset`).forEach((preview) => {
|
||||||
|
preview.style.display = "none";
|
||||||
|
});
|
||||||
|
} else if (type == filter.value) {
|
||||||
|
document.querySelectorAll(`.${type}-asset`).forEach((preview) => {
|
||||||
|
preview.style.display = "block";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("dropdown-filters-button").innerHTML = `
|
||||||
|
<span class="inline-flex items-center">
|
||||||
|
${filter.value.charAt(0).toUpperCase() + filter.value.slice(1)} Assets
|
||||||
|
<svg class="w-2.5 h-2.5 ms-2.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
|
||||||
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 4 4 4-4"/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* toggleYear shows or hides year input
|
* toggleYear shows or hides year input
|
||||||
* @param {string} type of asset
|
* @param {string} type of asset
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const factSubmitButton = document.getElementById("factSubmitButton");
|
|||||||
var path = window.location.pathname;
|
var path = window.location.pathname;
|
||||||
var page = path.split("/").pop();
|
var page = path.split("/").pop();
|
||||||
|
|
||||||
if(page !== "login" && page !== "signup" && page !== "forgotPassword" && page !== "") {
|
if(page !== "login" && page !== "signup" && page !== "forgotPassword" && page !== "aboutUs" && page !== "") {
|
||||||
factButton.classList.remove("hidden");
|
factButton.classList.remove("hidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const newPlanError = document.getElementById('newPlanError');
|
const newPlanError = document.getElementById('newPlanError');
|
||||||
const resetNewPlanFormBtn = document.getElementById('resetNewPlanFormBtn');
|
const resetNewPlanFormBtn = document.getElementById('resetNewPlanFormBtn');
|
||||||
|
|
||||||
|
let url = new URLSearchParams(window.location.search);
|
||||||
|
let modalValue = url.get('openModal');
|
||||||
|
|
||||||
|
if (modalValue === 'true') {
|
||||||
|
newPlanDialog.showModal();
|
||||||
|
}
|
||||||
|
|
||||||
openModalBtn.addEventListener('click', () => {
|
openModalBtn.addEventListener('click', () => {
|
||||||
newPlanDialog.showModal();
|
newPlanDialog.showModal();
|
||||||
// Error reset is now handled by 'close' event, but good to clear on open too
|
// Error reset is now handled by 'close' event, but good to clear on open too
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" fill="white" viewBox="0 0 24 24" aria-hidden="true">
|
||||||
<path d="M10.464 8.746c.227-.18.497-.311.786-.394v2.795a2.252 2.252 0 0 1-.786-.393c-.394-.313-.546-.681-.546-1.004 0-.323.152-.691.546-1.004ZM12.75 15.662v-2.824c.347.085.664.228.921.421.427.32.579.686.579.991 0 .305-.152.671-.579.991a2.534 2.534 0 0 1-.921.42Z" />
|
<path d="M10.464 8.746c.227-.18.497-.311.786-.394v2.795a2.252 2.252 0 0 1-.786-.393c-.394-.313-.546-.681-.546-1.004 0-.323.152-.691.546-1.004ZM12.75 15.662v-2.824c.347.085.664.228.921.421.427.32.579.686.579.991 0 .305-.152.671-.579.991a2.534 2.534 0 0 1-.921.42Z" />
|
||||||
<path fill-rule="evenodd" d="M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25ZM12.75 6a.75.75 0 0 0-1.5 0v.816a3.836 3.836 0 0 0-1.72.756c-.712.566-1.112 1.35-1.112 2.178 0 .829.4 1.612 1.113 2.178.502.4 1.102.647 1.719.756v2.978a2.536 2.536 0 0 1-.921-.421l-.879-.66a.75.75 0 0 0-.9 1.2l.879.66c.533.4 1.169.645 1.821.75V18a.75.75 0 0 0 1.5 0v-.81a4.124 4.124 0 0 0 1.821-.749c.745-.559 1.179-1.344 1.179-2.191 0-.847-.434-1.632-1.179-2.191a4.122 4.122 0 0 0-1.821-.75V8.354c.29.082.559.213.786.393l.415.33a.75.75 0 0 0 .933-1.175l-.415-.33a3.836 3.836 0 0 0-1.719-.755V6Z" clip-rule="evenodd" />
|
<path fill-rule="evenodd" d="M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25ZM12.75 6a.75.75 0 0 0-1.5 0v.816a3.836 3.836 0 0 0-1.72.756c-.712.566-1.112 1.35-1.112 2.178 0 .829.4 1.612 1.113 2.178.502.4 1.102.647 1.719.756v2.978a2.536 2.536 0 0 1-.921-.421l-.879-.66a.75.75 0 0 0-.9 1.2l.879.66c.533.4 1.169.645 1.821.75V18a.75.75 0 0 0 1.5 0v-.81a4.124 4.124 0 0 0 1.821-.749c.745-.559 1.179-1.344 1.179-2.191 0-.847-.434-1.632-1.179-2.191a4.122 4.122 0 0 0-1.821-.75V8.354c.29.082.559.213.786.393l.415.33a.75.75 0 0 0 .933-1.175l-.415-.33a3.836 3.836 0 0 0-1.719-.755V6Z" clip-rule="evenodd" />
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
@@ -1,3 +1,3 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" fill="currentColor" viewBox="0 0 24 24">
|
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" fill="white" viewBox="0 0 24 24">
|
||||||
<path fill-rule="evenodd" d="M11.293 3.293a1 1 0 0 1 1.414 0l6 6 2 2a1 1 0 0 1-1.414 1.414L19 12.414V19a2 2 0 0 1-2 2h-3a1 1 0 0 1-1-1v-3h-2v3a1 1 0 0 1-1 1H7a2 2 0 0 1-2-2v-6.586l-.293.293a1 1 0 0 1-1.414-1.414l2-2 6-6Z" clip-rule="evenodd"/>
|
<path fill-rule="evenodd" d="M11.293 3.293a1 1 0 0 1 1.414 0l6 6 2 2a1 1 0 0 1-1.414 1.414L19 12.414V19a2 2 0 0 1-2 2h-3a1 1 0 0 1-1-1v-3h-2v3a1 1 0 0 1-1 1H7a2 2 0 0 1-2-2v-6.586l-.293.293a1 1 0 0 1-1.414-1.414l2-2 6-6Z" clip-rule="evenodd"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 358 B After Width: | Height: | Size: 351 B |
@@ -1,3 +1,3 @@
|
|||||||
<svg height="30" width="30" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 17 14">
|
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" fill="white" viewBox="0 0 24 24">
|
||||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 1h15M1 7h15M1 13h15"></path>
|
<path stroke="white" stroke-linecap="round" stroke-width="2" d="M5 6h14 M5 14h14 M5 22h14"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 260 B After Width: | Height: | Size: 199 B |
@@ -1,3 +1,3 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" fill="currentColor" viewBox="0 0 24 24">
|
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" fill="white" viewBox="0 0 24 24">
|
||||||
<path d="M13.09 3.294c1.924.95 3.422 1.69 5.472.692a1 1 0 0 1 1.438.9v9.54a1 1 0 0 1-.562.9c-2.981 1.45-5.382.24-7.25-.701a38.739 38.739 0 0 0-.622-.31c-1.033-.497-1.887-.812-2.756-.77-.76.036-1.672.357-2.81 1.396V21a1 1 0 1 1-2 0V4.971a1 1 0 0 1 .297-.71c1.522-1.506 2.967-2.185 4.417-2.255 1.407-.068 2.653.453 3.72.967.225.108.443.216.655.32Z"/>
|
<path d="M13.09 3.294c1.924.95 3.422 1.69 5.472.692a1 1 0 0 1 1.438.9v9.54a1 1 0 0 1-.562.9c-2.981 1.45-5.382.24-7.25-.701a38.739 38.739 0 0 0-.622-.31c-1.033-.497-1.887-.812-2.756-.77-.76.036-1.672.357-2.81 1.396V21a1 1 0 1 1-2 0V4.971a1 1 0 0 1 .297-.71c1.522-1.506 2.967-2.185 4.417-2.255 1.407-.068 2.653.453 3.72.967.225.108.443.216.655.32Z"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 463 B After Width: | Height: | Size: 456 B |
@@ -24,7 +24,7 @@ const getAssetSchema = (type) => {
|
|||||||
assetSchema = joi.object({
|
assetSchema = joi.object({
|
||||||
type: joi.string().valid("other", "stock", "saving").required(),
|
type: joi.string().valid("other", "stock", "saving").required(),
|
||||||
icon: joi.string().alphanum().required(),
|
icon: joi.string().alphanum().required(),
|
||||||
name: joi.string().alphanum().min(3).max(30).required(),
|
name: joi.string().min(3).max(30).required(),
|
||||||
value: joi.number().min(0).required(),
|
value: joi.number().min(0).required(),
|
||||||
year: joi.number().min(1900).max(new Date().getFullYear()),
|
year: joi.number().min(1900).max(new Date().getFullYear()),
|
||||||
purchaseDate: joi.date().required(),
|
purchaseDate: joi.date().required(),
|
||||||
@@ -36,7 +36,7 @@ const getAssetSchema = (type) => {
|
|||||||
case "saving":
|
case "saving":
|
||||||
assetSchema = joi.object({
|
assetSchema = joi.object({
|
||||||
type: joi.string().valid("other", "stock", "saving").required(),
|
type: joi.string().valid("other", "stock", "saving").required(),
|
||||||
name: joi.string().alphanum().min(3).max(30).required(),
|
name: joi.string().min(3).max(30).required(),
|
||||||
value: joi.number().min(0).required(),
|
value: joi.number().min(0).required(),
|
||||||
id: joi.string().alphanum(), // May be passed when updating existing asset
|
id: joi.string().alphanum(), // May be passed when updating existing asset
|
||||||
userId: joi.string().alphanum(),
|
userId: joi.string().alphanum(),
|
||||||
@@ -45,7 +45,7 @@ const getAssetSchema = (type) => {
|
|||||||
case "stock":
|
case "stock":
|
||||||
assetSchema = joi.object({
|
assetSchema = joi.object({
|
||||||
type: joi.string().valid("other", "stock", "saving").required(),
|
type: joi.string().valid("other", "stock", "saving").required(),
|
||||||
ticker: joi.string().alphanum().min(3).max(5).required(),
|
ticker: joi.string().min(3).max(5).required(),
|
||||||
price: joi.number().min(0).required(),
|
price: joi.number().min(0).required(),
|
||||||
quantity: joi.number().min(1).required(),
|
quantity: joi.number().min(1).required(),
|
||||||
purchaseDate: joi.date().required(),
|
purchaseDate: joi.date().required(),
|
||||||
@@ -109,6 +109,12 @@ module.exports = (middleware, users, plans, assets) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.get('/assets', async (req, res) => {
|
router.get('/assets', async (req, res) => {
|
||||||
|
|
||||||
|
if (!req.session.user.financialData || !req.session.user) {
|
||||||
|
req.session.errMessage = "Please complete your financial data before creating a plan.";
|
||||||
|
return res.status(status.Unauthorized).redirect('/questionnaire');
|
||||||
|
}
|
||||||
|
|
||||||
let userAssets = await assets.find({ userId: new ObjectId(req.session.userId) }).toArray();
|
let userAssets = await assets.find({ userId: new ObjectId(req.session.userId) }).toArray();
|
||||||
let totalUserAssetValue = await calculateTotalAssetValue(userAssets);
|
let totalUserAssetValue = await calculateTotalAssetValue(userAssets);
|
||||||
|
|
||||||
@@ -124,6 +130,12 @@ module.exports = (middleware, users, plans, assets) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.get('/plans', async (req, res) => {
|
router.get('/plans', async (req, res) => {
|
||||||
|
|
||||||
|
if (!req.session.user.financialData || !req.session.user) {
|
||||||
|
req.session.errMessage = "Please complete your financial data before creating a plan.";
|
||||||
|
return res.status(status.Unauthorized).redirect('/questionnaire');
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
const updatedUserPlans = await updateProgress(plans, assets, users, req.session.user._id);
|
const updatedUserPlans = await updateProgress(plans, assets, users, req.session.user._id);
|
||||||
@@ -160,6 +172,8 @@ module.exports = (middleware, users, plans, assets) => {
|
|||||||
|
|
||||||
const progress = await calculateProgress(plan, assets, users, req.session.userId);
|
const progress = await calculateProgress(plan, assets, users, req.session.userId);
|
||||||
|
|
||||||
|
const suggestions = await generateSuggestions(totalUserAssetValue, plan);
|
||||||
|
|
||||||
res.render('planDetail', {
|
res.render('planDetail', {
|
||||||
user: req.session.user,
|
user: req.session.user,
|
||||||
plan: plan,
|
plan: plan,
|
||||||
@@ -167,7 +181,7 @@ module.exports = (middleware, users, plans, assets) => {
|
|||||||
totalUserAssetValue: totalUserAssetValue,
|
totalUserAssetValue: totalUserAssetValue,
|
||||||
assets: userAssets,
|
assets: userAssets,
|
||||||
progress: progress,
|
progress: progress,
|
||||||
suggestions: await suggestions.generateSuggestions(),
|
suggestions: suggestions,
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -177,21 +191,13 @@ module.exports = (middleware, users, plans, assets) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/newPlan', (req, res) => {
|
router.post('/newPlan', async (req, res) => {
|
||||||
|
|
||||||
if (!req.session.user.financialData || !req.session.user) {
|
if (!req.session.user.financialData || !req.session.user) {
|
||||||
req.session.errMessage = "Please complete your financial data before creating a plan.";
|
req.session.errMessage = "Please complete your financial data before creating a plan.";
|
||||||
return res.status(status.Unauthorized).redirect('/questionnaire');
|
return res.status(status.Unauthorized).redirect('/questionnaire');
|
||||||
}
|
}
|
||||||
const errMessage = req.session.errMessage;
|
|
||||||
req.session.errMessage = "";
|
|
||||||
res.render('newPlan', {
|
|
||||||
user: req.session.user,
|
|
||||||
errMessage: errMessage,
|
|
||||||
geoData: req.session.geoData
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
router.post('/newPlan', async (req, res) => {
|
|
||||||
const planSchema = joi.object({
|
const planSchema = joi.object({
|
||||||
name: joi.string().min(3).max(100).required(),
|
name: joi.string().min(3).max(100).required(),
|
||||||
retirementAge: joi.number().min(18).max(120).required(),
|
retirementAge: joi.number().min(18).max(120).required(),
|
||||||
@@ -459,7 +465,7 @@ module.exports = (middleware, users, plans, assets) => {
|
|||||||
router.post("/updateAccount", async (req, res) => {
|
router.post("/updateAccount", async (req, res) => {
|
||||||
const accountSchema = joi.object({
|
const accountSchema = joi.object({
|
||||||
email: joi.string().email({ minDomainSegments: 2, tlds: { allow: true } }),
|
email: joi.string().email({ minDomainSegments: 2, tlds: { allow: true } }),
|
||||||
name: joi.string().pattern(new RegExp('^[a-zA-Z]+$')).max(20),
|
name: joi.string().pattern(new RegExp('^[a-zA-Z0-9_ ]*$')).max(20),
|
||||||
password: joi.string().max(20).min(8),
|
password: joi.string().max(20).min(8),
|
||||||
repassword: joi.string().max(20).min(8),
|
repassword: joi.string().max(20).min(8),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -45,25 +45,41 @@ async function updatePlanProgressInDB(planId, percentage, plans) {
|
|||||||
async function calculateTotalAssetValue(assets) {
|
async function calculateTotalAssetValue(assets) {
|
||||||
if (!assets || typeof assets.find !== 'function') {
|
if (!assets || typeof assets.find !== 'function') {
|
||||||
console.error("Error with the assets collection");
|
console.error("Error with the assets collection");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
let totalAssetValue = 0;
|
let totalAssetValue = 0;
|
||||||
|
const today = new Date();
|
||||||
|
|
||||||
for (const asset of assets) {
|
for (const asset of assets) {
|
||||||
if(asset.icon == "Motorcycle" || asset.icon == "Car"){
|
if (asset.icon === "Motorcycle" || asset.icon === "Car") {
|
||||||
today = new Date();
|
if (asset.value < 1000) {
|
||||||
asset.year = new Date(asset.year).getFullYear();
|
totalAssetValue += asset.value;
|
||||||
let age = today.getFullYear() - asset.year;
|
} else {
|
||||||
let value = asset.value * Math.pow(0.85, age);
|
const assetYear = asset.year;
|
||||||
totalAssetValue += value;
|
const age = today.getFullYear() - assetYear;
|
||||||
|
let depreciatedValue;
|
||||||
|
|
||||||
|
if (age < 1){
|
||||||
|
depreciatedValue = asset.value * 0.9;
|
||||||
|
}else{
|
||||||
|
depreciatedValue = asset.value * Math.pow(0.90, age);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depreciatedValue < 1000) {
|
||||||
|
totalAssetValue += 1000;
|
||||||
|
} else {
|
||||||
|
totalAssetValue += depreciatedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
totalAssetValue += asset.value;
|
totalAssetValue += asset.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return totalAssetValue;
|
return totalAssetValue;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error in calculateTotalAssetValue:", err);
|
console.error("Error in calculateTotalAssetValue:", err);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,6 +134,10 @@ async function calculateProgress(plan, assets, users, userId) {
|
|||||||
const monthlyInvestment = (totalUserPlanValue - totalUserAssetValue + totalCostOfRetirement) / monthsUntilRetirement;
|
const monthlyInvestment = (totalUserPlanValue - totalUserAssetValue + totalCostOfRetirement) / monthsUntilRetirement;
|
||||||
|
|
||||||
const percentageCalculated = (totalUserAssetValue / (totalUserPlanValue + totalCostOfRetirement)) * 100;
|
const percentageCalculated = (totalUserAssetValue / (totalUserPlanValue + totalCostOfRetirement)) * 100;
|
||||||
|
|
||||||
|
if (monthsUntilRetirement <= 0) {
|
||||||
|
return { monthlyInvestment: 0, totalCostOfRetirement: totalCostOfRetirement, monthsUntilRetirement: 0, yearsRetired: yearsRetired, yearsUntilRetirement: 0, percentage: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
const progress = {};
|
const progress = {};
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,14 @@ async function generateFact(factInput) {
|
|||||||
return response.text;
|
return response.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function generateSuggestions() {
|
async function generateSuggestions(totalUserAssetValue, plan) {
|
||||||
const response = await ai.models.generateContent({
|
const response = await ai.models.generateContent({
|
||||||
model: "gemini-2.0-flash",
|
model: "gemini-2.0-flash",
|
||||||
contents: "Return a mock investment suggestion 3-5 lines only",
|
contents: `Return an investment suggestion 3-5 based on the user's total asset value and their plan. Please do not include any extra text or explanation.
|
||||||
|
|
||||||
|
Total User Asset Value: ${totalUserAssetValue}
|
||||||
|
|
||||||
|
Plan: ${plan}`,
|
||||||
});
|
});
|
||||||
return response.text;
|
return response.text;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,27 +10,59 @@
|
|||||||
<section class="bg-gray-900 py-12 md:py-20">
|
<section class="bg-gray-900 py-12 md:py-20">
|
||||||
<div class="max-w-screen-lg mx-auto px-4 text-center">
|
<div class="max-w-screen-lg mx-auto px-4 text-center">
|
||||||
<h1 class="mb-4 text-4xl font-extrabold tracking-tight leading-none md:text-5xl lg:text-6xl text-white">About RCalculator</h1>
|
<h1 class="mb-4 text-4xl font-extrabold tracking-tight leading-none md:text-5xl lg:text-6xl text-white">About RCalculator</h1>
|
||||||
<p class="mb-12 text-lg font-normal lg:text-xl sm:px-16 text-gray-400">Welcome to RCalculator, your partner in building a secure and fulfilling financial future.</p>
|
<p class="mb-12 text-lg font-normal lg:text-xl sm:px-16 text-gray-400">Welcome to RCalculator, your partner in navigating the path to a secure and fulfilling financial future. We simplify financial planning, making it accessible and actionable for everyone.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="max-w-screen-md mx-auto px-4">
|
<!-- What RCalculator Offers Section -->
|
||||||
<h2 class="mb-4 text-3xl font-bold tracking-tight text-white text-center">Our Mission</h2>
|
<div class="max-w-screen-md mx-auto px-4 mb-16">
|
||||||
<p class="mb-6 font-normal text-gray-400 text-lg text-center">
|
<h2 class="mb-8 text-3xl font-bold tracking-tight text-white text-center">What RCalculator Offers</h2>
|
||||||
Our mission is to empower you with the tools and insights needed to take control of your long-term financial goals.
|
<div class="space-y-8 text-gray-400 text-lg">
|
||||||
</p>
|
<div class="p-6 border border-gray-700 rounded-lg bg-gray-800/30 shadow-lg">
|
||||||
<div class="prose lg:prose-lg mx-auto text-gray-400">
|
<h3 class="font-semibold text-xl text-white mb-2">Personalized Financial Insights</h3>
|
||||||
<p class="mb-4">
|
<p>Start by completing our comprehensive questionnaire. Your answers help us tailor financial guidance and projections specifically to your situation and goals.</p>
|
||||||
We believe that planning for your desired future, especially retirement, shouldn't be daunting. It doesn't matter what your current age or career status is – starting now is what counts.
|
</div>
|
||||||
</p>
|
<div class="p-6 border border-gray-700 rounded-lg bg-gray-800/30 shadow-lg">
|
||||||
<p class="mb-4">
|
<h3 class="font-semibold text-xl text-white mb-2">Comprehensive Asset Tracking</h3>
|
||||||
At RCalculator, we help you trace a personalized plan that suits your unique aspirations. We provide clear, actionable advice and projections to guide you on how to get there, whether you're just starting your career, mid-way through, or nearing retirement.
|
<p>Easily add and monitor various types of assets, from savings accounts and stocks to real estate and other investments. Get a clear overview of your net worth in one place.</p>
|
||||||
</p>
|
</div>
|
||||||
<p>
|
<div class="p-6 border border-gray-700 rounded-lg bg-gray-800/30 shadow-lg">
|
||||||
Let us help you navigate the path to financial independence and achieve the retirement lifestyle you envision.
|
<h3 class="font-semibold text-xl text-white mb-2">Strategic Goal Planning</h3>
|
||||||
</p>
|
<p>Define your long-term financial objectives, such as retirement, buying a home, or funding education. Create detailed plans and see how you can achieve them.</p>
|
||||||
|
</div>
|
||||||
|
<div class="p-6 border border-gray-700 rounded-lg bg-gray-800/30 shadow-lg">
|
||||||
|
<h3 class="font-semibold text-xl text-white mb-2">Clear Financial Projections</h3>
|
||||||
|
<p>Understand the potential growth of your investments and the feasibility of your financial plans with our easy-to-understand projections and visual tools.</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Getting Started Section -->
|
||||||
|
<div class="max-w-screen-md mx-auto px-4 mb-16">
|
||||||
|
<h2 class="mb-8 text-3xl font-bold tracking-tight text-white text-center">Getting Started with RCalculator</h2>
|
||||||
|
<ol class="list-decimal list-inside space-y-6 text-gray-400 text-lg">
|
||||||
|
<li class="p-4 border border-gray-700 rounded-lg bg-gray-800 shadow-md">
|
||||||
|
<span class="font-semibold text-white">Sign Up & Build Your Profile:</span> Create your account and fill out our initial questionnaire. This provides the foundation for personalized advice.
|
||||||
|
</li>
|
||||||
|
<li class="p-4 border border-gray-700 rounded-lg bg-gray-800 shadow-md">
|
||||||
|
<span class="font-semibold text-white">Log Your Assets:</span> Navigate to the 'Assets' section to add details about your current savings, investments, and other valuable possessions.
|
||||||
|
</li>
|
||||||
|
<li class="p-4 border border-gray-700 rounded-lg bg-gray-800 shadow-md">
|
||||||
|
<span class="font-semibold text-white">Create Financial Plans:</span> Head to the 'Plans' section to outline your financial goals. Set targets, timelines, and see projected outcomes.
|
||||||
|
</li>
|
||||||
|
<li class="p-4 border border-gray-700 rounded-lg bg-gray-800 shadow-md">
|
||||||
|
<span class="font-semibold text-white">Monitor & Adjust:</span> Regularly review your dashboard to track your progress. Adjust your plans and asset information as your circumstances change.
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Our Commitment Section -->
|
||||||
|
<div class="max-w-screen-md mx-auto px-4">
|
||||||
|
<h2 class="mb-6 text-3xl font-bold tracking-tight text-white text-center">Our Commitment</h2>
|
||||||
|
<p class="text-gray-400 text-lg text-center">
|
||||||
|
Our mission is to empower you with clarity and confidence in your financial decisions. We believe that with the right tools and guidance, anyone can achieve their financial aspirations. Let RCalculator be your guide to financial independence.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<% if (!geoData) { %>
|
<% if (!geoData) { %>
|
||||||
<div class="flex flex-col space-y-4 sm:flex-row sm:justify-center sm:space-y-0">
|
<div class="flex flex-col space-y-4 sm:flex-row sm:justify-center sm:space-y-0">
|
||||||
<a href="/signup" class="inline-flex justify-center items-center mt-4 py-3 px-5 text-base font-medium text-center text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-900">
|
<a href="/signup" class="inline-flex justify-center items-center mt-4 py-3 px-5 text-base font-medium text-center text-white rounded-lg bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-900">
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<!-- Main display -->
|
<!-- Main display -->
|
||||||
<section>
|
<section>
|
||||||
<div class="mt-2 max-w-md mx-auto bg-white px-8 py-6 rounded-lg shadow-md flex flex-col justify-center">
|
<div class="my-2 mx-4 md:max-w-md md:mx-auto bg-white px-8 py-6 rounded-lg shadow-md flex flex-col justify-center">
|
||||||
<div class="flex flex-row justify-between text-right">
|
<div class="flex flex-row justify-between text-right">
|
||||||
<h1 class="text-lg font-medium">Assets:</h1>
|
<h1 class="text-lg font-medium">Assets:</h1>
|
||||||
<h1 class="text-lg font-medium"><%= assets.length %></h1>
|
<h1 class="text-lg font-medium"><%= assets.length %></h1>
|
||||||
@@ -24,12 +24,51 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w-md my-6 max-w-md mx-auto px-4 flex flex-row justify-between">
|
<div class="my-6 md:w-md md:mx-auto px-4 flex flex-row justify-between">
|
||||||
<a href="/home" class="text-center w-sm py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
|
||||||
Back to Dashboard
|
|
||||||
</a>
|
|
||||||
<button
|
<button
|
||||||
class="text-center w-sm py-2 py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 cursor-pointer"
|
id="dropdown-filters-button"
|
||||||
|
value=""
|
||||||
|
data-dropdown-toggle="dropdown-filters"
|
||||||
|
class="text-center w-sm py-2 mx-2 px-4 border
|
||||||
|
border-transparent rounded-md shadow-sm text-sm font-medium
|
||||||
|
text-white bg-blue-600 hover:bg-blue-700 focus:outline-none cursor-pointer"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span class="inline-flex items-center">
|
||||||
|
All Assets
|
||||||
|
<svg class="w-2.5 h-2.5 ms-2.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
|
||||||
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 4 4 4-4"/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<div id="dropdown-filters" class="overflow-y-auto h-40 z-10 hidden divide-y divide-gray-100 rounded-lg shadow-sm w-32 bg-gray-700">
|
||||||
|
<ul id="dropdown-filters-ul" class="py-2 text-sm text-gray-200" aria-labelledby="dropdown-filters-button">
|
||||||
|
<li>
|
||||||
|
<button onclick="selectFilter(this)" type="button" value="all" class="inline-flex w-full px-4 py-2 text-sm text-gray-200 hover:bg-gray-600 hover:text-white" role="menuitem">
|
||||||
|
<span class="inline-flex items-center">All Assets</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button onclick="selectFilter(this)" type="button" value="other" class="inline-flex w-full px-4 py-2 text-sm text-gray-200 hover:bg-gray-600 hover:text-white" role="menuitem">
|
||||||
|
<span class="inline-flex items-center">Other Assets</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button onclick="selectFilter(this)" type="button" value="saving" class="inline-flex w-full px-4 py-2 text-sm text-gray-200 hover:bg-gray-600 hover:text-white" role="menuitem">
|
||||||
|
<span class="inline-flex items-center">Savings Assets</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button onclick="selectFilter(this)" type="button" value="stock" class="inline-flex w-full px-4 py-2 text-sm text-gray-200 hover:bg-gray-600 hover:text-white" role="menuitem">
|
||||||
|
<span class="inline-flex items-center">Stocks Assets</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="text-center w-sm py-2 py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600
|
||||||
|
hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 cursor-pointer"
|
||||||
onclick="document.getElementById('create-asset-modal').showModal()"
|
onclick="document.getElementById('create-asset-modal').showModal()"
|
||||||
>
|
>
|
||||||
Add New Asset
|
Add New Asset
|
||||||
@@ -40,7 +79,7 @@
|
|||||||
<hr class="h-px my-8 bg-gray-500 border-0 mx-10">
|
<hr class="h-px my-8 bg-gray-500 border-0 mx-10">
|
||||||
|
|
||||||
<!-- list each asset and create hidden popup modal for view/edit -->
|
<!-- list each asset and create hidden popup modal for view/edit -->
|
||||||
<section class="mt-6">
|
<section class="my-6 mx-4">
|
||||||
<% if (assets.length == 0) { %>
|
<% if (assets.length == 0) { %>
|
||||||
<div class="max-w-md mx-auto mb-10 rounded-lg shadow-md text-white font-bold bg-red-400 py-4 text-center">
|
<div class="max-w-md mx-auto mb-10 rounded-lg shadow-md text-white font-bold bg-red-400 py-4 text-center">
|
||||||
You have no assets, create a new asset.
|
You have no assets, create a new asset.
|
||||||
|
|||||||
@@ -3,27 +3,28 @@
|
|||||||
|
|
||||||
<main class="pt-24 pb-14">
|
<main class="pt-24 pb-14">
|
||||||
<!-- Buttons -->
|
<!-- Buttons -->
|
||||||
<div class="flex justify-end gap-4 px-5 py-6">
|
<div class="flex md:justify-end justify-center gap-4 px-5 py-6 md:py-0">
|
||||||
<a href="/assets?popup"
|
<a href="/assets?popup"
|
||||||
class="text-center cursor-pointer min-w-[150px] bg-green-600 px-4 py-2 text-white rounded hover:bg-green-800"
|
id="addAss" class="text-center cursor-pointer min-w-[150px] bg-green-600 px-4 py-2 text-white rounded hover:bg-green-800"
|
||||||
type="button">Add Asset</a>
|
type="button">Add Asset</a>
|
||||||
<a href="/newPlan"
|
<a href="/plans?openModal=true"
|
||||||
class="text-center cursor-pointer min-w-[150px] bg-green-600 px-4 py-2 text-white rounded hover:bg-green-800"
|
class="text-center cursor-pointer min-w-[150px] bg-green-600 px-4 py-2 text-white rounded hover:bg-green-800"
|
||||||
type="button">Create new plan </a>
|
type="button">Create new plan </a>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<div class="mb-12 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-y-4 gap-x-6">
|
<div class="mb-12 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-y-4 gap-x-6">
|
||||||
<% if (plans.length === 0) { %>
|
<% if (plans.length === 0) { %>
|
||||||
<div class="col-span-1 col-start-2 ml-28 mt-25">
|
<div class="flex justify-center md:col-start-2">
|
||||||
<div class="w-86 p-4 bg-white rounded-lg shadow-xl border border-slate-200">
|
<div class="col-span-1 mt-25">
|
||||||
<h1 class="text-2xl block text-center font-semibold text-slate-700">Don't have any retirement plans? </h1>
|
<div class="w-86 p-4 bg-white rounded-lg shadow-xl border border-slate-200">
|
||||||
<div class="mt-4 flex justify-center items-center">
|
<h1 class="text-2xl block text-center font-semibold text-slate-700">Don't have any retirement plans? </h1>
|
||||||
<div class="mt-4 flex justify-center">
|
<div class="mt-4 flex justify-center items-center">
|
||||||
<a href="/plans" class="cursor-pointer border-2 border-indigo-600 bg-indigo-600 text-white py-2 px-6
|
<div class="mt-4 flex justify-center">
|
||||||
rounded-md hover:bg-indigo-700 hover:border-indigo-700 font-semibold
|
<a href="/plans" class="cursor-pointer border-2 border-blue-600 bg-blue-600 text-white py-2 px-6
|
||||||
transition-colors duration-200 focus:outline-none focus:ring-2
|
rounded-md hover:bg-blue-700 hover:border-blue-700 font-semibold
|
||||||
focus:ring-indigo-500 focus:ring-offset-2">Make one</a>
|
transition-colors duration-200 focus:outline-none ">Make one</a>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,44 +10,44 @@
|
|||||||
<div>
|
<div>
|
||||||
<label for="name" class="block text-sm font-medium text-gray-300">Plan Name <span class="text-red-500">*</span></label>
|
<label for="name" class="block text-sm font-medium text-gray-300">Plan Name <span class="text-red-500">*</span></label>
|
||||||
<input type="text" name="name" id="name" value="<%= plan.name %>" required
|
<input type="text" name="name" id="name" value="<%= plan.name %>" required
|
||||||
class="mt-1 block w-full px-4 py-2 border border-gray-600 rounded-md shadow-sm bg-gray-700 text-white focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm placeholder-gray-400">
|
class="mt-1 block w-full px-4 py-2 border border-gray-600 rounded-md shadow-sm bg-gray-700 text-white focus:ring-blue-500 focus:border-blue-500 sm:text-sm placeholder-gray-400">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="retirementAge" class="block text-sm font-medium text-gray-300">Desired Retirement Age <span class="text-red-500">*</span></label>
|
<label for="retirementAge" class="block text-sm font-medium text-gray-300">Desired Retirement Age <span class="text-red-500">*</span></label>
|
||||||
<input type="number" name="retirementAge" id="retirementAge" value="<%= plan.retirementAge %>" required min="18"
|
<input type="number" name="retirementAge" id="retirementAge" value="<%= plan.retirementAge %>" required min="18"
|
||||||
class="mt-1 block w-full px-4 py-2 border border-gray-600 rounded-md shadow-sm bg-gray-700 text-white focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm placeholder-gray-400">
|
class="mt-1 block w-full px-4 py-2 border border-gray-600 rounded-md shadow-sm bg-gray-700 text-white focus:ring-blue-500 focus:border-blue-500 sm:text-sm placeholder-gray-400">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="retirementExpenses" class="block text-sm font-medium text-gray-300">Estimated Monthly Expenses at Retirement (<%= geoData.currency || 'CAD' %>) <span class="text-red-500">*</span></label>
|
<label for="retirementExpenses" class="block text-sm font-medium text-gray-300">Estimated Monthly Expenses at Retirement (<%= geoData.currency || 'CAD' %>) <span class="text-red-500">*</span></label>
|
||||||
<input type="number" name="retirementExpenses" id="retirementExpenses" value="<%= plan.retirementExpenses %>" required min="0" step="any"
|
<input type="number" name="retirementExpenses" id="retirementExpenses" value="<%= plan.retirementExpenses %>" required min="0" step="any"
|
||||||
class="mt-1 block w-full px-4 py-2 border border-gray-600 rounded-md shadow-sm bg-gray-700 text-white focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm placeholder-gray-400">
|
class="mt-1 block w-full px-4 py-2 border border-gray-600 rounded-md shadow-sm bg-gray-700 text-white focus:ring-blue-500 focus:border-blue-500 sm:text-sm placeholder-gray-400">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="retirementAssets" class="block text-sm font-medium text-gray-300">Target Retirement Assets (<%= geoData.currency || 'CAD' %>) <span class="text-red-500">*</span></label>
|
<label for="retirementAssets" class="block text-sm font-medium text-gray-300">Target Retirement Assets (<%= geoData.currency || 'CAD' %>) <span class="text-red-500">*</span></label>
|
||||||
<input type="number" name="retirementAssets" id="retirementAssets" value="<%= plan.retirementAssets %>" required min="0" step="any"
|
<input type="number" name="retirementAssets" id="retirementAssets" value="<%= plan.retirementAssets %>" required min="0" step="any"
|
||||||
class="mt-1 block w-full px-4 py-2 border border-gray-600 rounded-md shadow-sm bg-gray-700 text-white focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm placeholder-gray-400">
|
class="mt-1 block w-full px-4 py-2 border border-gray-600 rounded-md shadow-sm bg-gray-700 text-white focus:ring-blue-500 focus:border-blue-500 sm:text-sm placeholder-gray-400">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="retirementLiabilities" class="block text-sm font-medium text-gray-300">Estimated Monthly Liabilities at Retirement (<%= geoData.currency || 'CAD' %>) <span class="text-red-500">*</span></label>
|
<label for="retirementLiabilities" class="block text-sm font-medium text-gray-300">Estimated Monthly Liabilities at Retirement (<%= geoData.currency || 'CAD' %>) <span class="text-red-500">*</span></label>
|
||||||
<input type="number" name="retirementLiabilities" id="retirementLiabilities" value="<%= plan.retirementLiabilities %>" required min="0" step="any"
|
<input type="number" name="retirementLiabilities" id="retirementLiabilities" value="<%= plan.retirementLiabilities %>" required min="0" step="any"
|
||||||
class="mt-1 block w-full px-4 py-2 border border-gray-600 rounded-md shadow-sm bg-gray-700 text-white focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm placeholder-gray-400">
|
class="mt-1 block w-full px-4 py-2 border border-gray-600 rounded-md shadow-sm bg-gray-700 text-white focus:ring-blue-500 focus:border-blue-500 sm:text-sm placeholder-gray-400">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="formErrorMessages" class="text-red-400 text-sm my-2" style="display: none;"></div>
|
<div id="formErrorMessages" class="text-red-400 text-sm my-2" style="display: none;"></div>
|
||||||
|
|
||||||
<div class="flex items-center justify-center space-x-4 pt-4">
|
<div class="flex items-center justify-center space-x-4 pt-4">
|
||||||
<button type="submit"
|
<button type="submit"
|
||||||
class="inline-flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-indigo-500">
|
class="inline-flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-blue-500">
|
||||||
Save Changes
|
Save Changes
|
||||||
</button>
|
</button>
|
||||||
<button type="button" id="resetButton" class="inline-flex justify-center py-2 px-4 border border-gray-600 rounded-md shadow-sm bg-gray-600 text-sm font-medium text-white hover:bg-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-indigo-500">
|
<button type="button" id="resetButton" class="inline-flex justify-center py-2 px-4 border border-gray-600 rounded-md shadow-sm bg-gray-600 text-sm font-medium text-white hover:bg-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-blue-500">
|
||||||
Reset
|
Reset
|
||||||
</button>
|
</button>
|
||||||
<a href="/plans/<%= plan._id %>" class="inline-flex justify-center py-2 px-4 border border-gray-600 rounded-md shadow-sm bg-gray-600 text-sm font-medium text-white hover:bg-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-indigo-500">
|
<a href="/plans/<%= plan._id %>" class="inline-flex justify-center py-2 px-4 border border-gray-600 rounded-md shadow-sm bg-gray-600 text-sm font-medium text-white hover:bg-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-blue-500">
|
||||||
Cancel
|
Cancel
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<label for="email" class="block text-base mb-2 text-slate-600">Email</label>
|
<label for="email" class="block text-base mb-2 text-slate-600">Email</label>
|
||||||
<input type="text" id="email" name="email"
|
<input type="text" id="email" name="email"
|
||||||
class="border border-slate-300 focus:border-indigo-500 w-full rounded-md text-base px-3 py-2 focus:outline-none focus:ring-1 focus:ring-indigo-500 transition-colors duration-200"
|
class="border border-slate-300 focus:border-blue-500 w-full rounded-md text-base px-3 py-2 focus:outline-none focus:ring-1 focus:ring-blue-500 transition-colors duration-200"
|
||||||
placeholder="Enter Email" />
|
placeholder="Enter Email" />
|
||||||
</div>
|
</div>
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
<% if (!reset) { %>
|
<% if (!reset) { %>
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
<button type="submit"
|
<button type="submit"
|
||||||
class="border-2 border-indigo-600 bg-indigo-600 text-white py-2 w-full rounded-md hover:bg-indigo-700 hover:border-indigo-700 font-semibold transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">Send Reset Link</button>
|
class="border-2 border-blue-600 bg-blue-600 text-white py-2 w-full rounded-md hover:bg-blue-700 hover:border-blue-700 font-semibold transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">Send Reset Link</button>
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,13 +11,13 @@
|
|||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<label for="email" class="block text-base mb-2 text-slate-600">Email <span class="text-red-500">*</span></label>
|
<label for="email" class="block text-base mb-2 text-slate-600">Email <span class="text-red-500">*</span></label>
|
||||||
<input required type="text" id="email" name="email"
|
<input required type="text" id="email" name="email"
|
||||||
class="border border-slate-300 focus:border-indigo-500 w-full rounded-md text-base px-3 py-2 focus:outline-none focus:ring-1 focus:ring-indigo-500 transition-colors duration-200"
|
class="border border-slate-300 focus:border-blue-500 w-full rounded-md text-base px-3 py-2 focus:outline-none focus:ring-1 focus:ring-blue-500 transition-colors duration-200"
|
||||||
placeholder="Enter Email" value="<%= typeof email != 'undefined' ? email : '' %>"/>
|
placeholder="Enter Email" value="<%= typeof email != 'undefined' ? email : '' %>"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<label for="password" class="block text-base mb-2 text-slate-600">Password <span class="text-red-500">*</span></label>
|
<label for="password" class="block text-base mb-2 text-slate-600">Password <span class="text-red-500">*</span></label>
|
||||||
<input required type="password" id="password" name="password"
|
<input required type="password" id="password" name="password"
|
||||||
class="border border-slate-300 focus:border-indigo-500 w-full rounded-md text-base px-3 py-2 focus:outline-none focus:ring-1 focus:ring-indigo-500 transition-colors duration-200"
|
class="border border-slate-300 focus:border-blue-500 w-full rounded-md text-base px-3 py-2 focus:outline-none focus:ring-1 focus:ring-blue-500 transition-colors duration-200"
|
||||||
placeholder="Enter Password" />
|
placeholder="Enter Password" />
|
||||||
</div>
|
</div>
|
||||||
<% if (errMessage && errMessage.length > 0) { %>
|
<% if (errMessage && errMessage.length > 0) { %>
|
||||||
@@ -27,20 +27,20 @@
|
|||||||
<% } %>
|
<% } %>
|
||||||
<div class="mt-4 flex justify-between items-center">
|
<div class="mt-4 flex justify-between items-center">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<input type="checkbox" id="rememberMe" class="h-4 w-4 text-indigo-600 border-slate-300 rounded focus:ring-indigo-500">
|
<input type="checkbox" id="rememberMe" class="h-4 w-4 text-blue-600 border-slate-300 rounded focus:ring-blue-500">
|
||||||
<label for="rememberMe" class="ml-2 text-sm text-slate-600">Remember me</label>
|
<label for="rememberMe" class="ml-2 text-sm text-slate-600">Remember me</label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a href="/forgotPassword" class="text-sm text-indigo-600 hover:text-indigo-500 font-semibold transition-colors duration-200">Forgot Password? </a>
|
<a href="/forgotPassword" class="text-sm text-blue-600 hover:text-blue-500 font-semibold transition-colors duration-200">Forgot Password? </a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
<button type="submit"
|
<button type="submit"
|
||||||
class="border-2 border-indigo-600 bg-indigo-600 text-white py-2 w-full rounded-md hover:bg-indigo-700 hover:border-indigo-700 font-semibold transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">Login</button>
|
class="border-2 border-blue-600 bg-blue-600 text-white py-2 w-full rounded-md hover:bg-blue-700 hover:border-blue-700 font-semibold transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">Login</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-6 text-center">
|
<div class="mt-6 text-center">
|
||||||
<span class="text-sm text-slate-600">Don't have an account?</span>
|
<span class="text-sm text-slate-600">Don't have an account?</span>
|
||||||
<a href="/signup" class="text-sm text-indigo-600 hover:text-indigo-500 font-semibold ml-1 transition-colors duration-200">Register</a>
|
<a href="/signup" class="text-sm text-blue-600 hover:text-blue-500 font-semibold ml-1 transition-colors duration-200">Register</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -15,16 +15,6 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a href="/settings" class="relative flex flex-col bg-clip-border rounded-xl bg-white text-gray-700 shadow-md">
|
|
||||||
<div class="p-4 flex items-center justify-between">
|
|
||||||
<p class="font-sans text-2xl leading-normal font-normal text-blue-gray-600">
|
|
||||||
Settings
|
|
||||||
</p>
|
|
||||||
<svg class="w-[40px] h-[40px]" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
|
|
||||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="m10 16 4-4-4-4"/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<a href="/aboutUs" class="relative flex flex-col bg-clip-border rounded-xl bg-white text-gray-700 shadow-md">
|
<a href="/aboutUs" class="relative flex flex-col bg-clip-border rounded-xl bg-white text-gray-700 shadow-md">
|
||||||
<div class="p-4 flex items-center justify-between">
|
<div class="p-4 flex items-center justify-between">
|
||||||
<p class="font-sans text-2xl leading-normal font-normal text-blue-gray-600">
|
<p class="font-sans text-2xl leading-normal font-normal text-blue-gray-600">
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
style="width: 100%;"
|
style="width: 100%;"
|
||||||
onclick="lockAsset('<%= asset._id %>', '<%= asset.icon %>')"
|
onclick="lockAsset('<%= asset._id %>', '<%= asset.icon %>')"
|
||||||
type="submit"
|
type="submit"
|
||||||
class="text-center w-sm py-2 py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 cursor-pointer"
|
class="text-center w-sm py-2 py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white
|
||||||
|
bg-blue-600 hover:bg-blue-700 focus:outline-none "
|
||||||
>
|
>
|
||||||
Close
|
Close
|
||||||
</button>
|
</button>
|
||||||
@@ -34,7 +35,7 @@
|
|||||||
id="dropdown-icon-button-<%= asset._id %>"
|
id="dropdown-icon-button-<%= asset._id %>"
|
||||||
value=""
|
value=""
|
||||||
data-dropdown-toggle="dropdown-icons-<%= asset._id %>"
|
data-dropdown-toggle="dropdown-icons-<%= asset._id %>"
|
||||||
class="shrink-0 z-10 inline-flex items-center py-2.5 px-4 text-sm font-medium text-center border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
class="shrink-0 z-10 inline-flex items-center py-2.5 px-4 text-sm font-medium text-center border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<img src="/static/svgs/icons/<%= asset.icon %>.svg" class="h-4 w-4 me-2" alt="<%= asset.icon %>"> <%= asset.icon %>
|
<img src="/static/svgs/icons/<%= asset.icon %>.svg" class="h-4 w-4 me-2" alt="<%= asset.icon %>"> <%= asset.icon %>
|
||||||
@@ -59,7 +60,7 @@
|
|||||||
<% } else { %>
|
<% } else { %>
|
||||||
<button
|
<button
|
||||||
disabled
|
disabled
|
||||||
class="inline-flex items-center py-2.5 px-10 text-sm font-medium text-center border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
class="inline-flex items-center py-2.5 px-10 text-sm font-medium text-center border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<img src="/static/svgs/icons/<%= asset.icon %>.svg" class="h-4 w-4" alt="<%= asset.icon %>">
|
<img src="/static/svgs/icons/<%= asset.icon %>.svg" class="h-4 w-4" alt="<%= asset.icon %>">
|
||||||
@@ -71,7 +72,7 @@
|
|||||||
<button
|
<button
|
||||||
id="edit-<%= asset._id %>"
|
id="edit-<%= asset._id %>"
|
||||||
onclick="unlockAsset('<%= asset._id %>')"
|
onclick="unlockAsset('<%= asset._id %>')"
|
||||||
class="py-3 px-8 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 cursor-pointer"
|
class="py-3 px-8 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 cursor-pointer"
|
||||||
>
|
>
|
||||||
Edit
|
Edit
|
||||||
</button>
|
</button>
|
||||||
@@ -93,7 +94,7 @@
|
|||||||
type="text"
|
type="text"
|
||||||
name="name"
|
name="name"
|
||||||
value="<%= asset.name %>"
|
value="<%= asset.name %>"
|
||||||
class="mt-1 mb-2 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
class="mt-1 mb-2 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
||||||
>
|
>
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
<label for="ticker" class="block text-sm font-medium text-gray-700 mt-2">Stock Ticker <span class="text-red-500">*</span></label>
|
<label for="ticker" class="block text-sm font-medium text-gray-700 mt-2">Stock Ticker <span class="text-red-500">*</span></label>
|
||||||
@@ -103,7 +104,7 @@
|
|||||||
type="text"
|
type="text"
|
||||||
name="ticker"
|
name="ticker"
|
||||||
value="<%= asset.ticker %>"
|
value="<%= asset.ticker %>"
|
||||||
class="mt-1 mb-2 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
class="mt-1 mb-2 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
||||||
>
|
>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
@@ -118,7 +119,7 @@
|
|||||||
step=".01"
|
step=".01"
|
||||||
name="value"
|
name="value"
|
||||||
value="<%= asset.value %>"
|
value="<%= asset.value %>"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
||||||
>
|
>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -137,7 +138,7 @@
|
|||||||
max="<% new Date().getFullYear() %>"
|
max="<% new Date().getFullYear() %>"
|
||||||
type="number"
|
type="number"
|
||||||
name="year"
|
name="year"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
||||||
value="<%= asset.year %>"
|
value="<%= asset.year %>"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -150,7 +151,7 @@
|
|||||||
step=".01"
|
step=".01"
|
||||||
name="price"
|
name="price"
|
||||||
value="<%= asset.price %>"
|
value="<%= asset.price %>"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
||||||
>
|
>
|
||||||
|
|
||||||
<label for="quantity" class="block text-sm font-medium text-gray-700 mt-2">Quantity of Shares <span class="text-red-500">*</span></label>
|
<label for="quantity" class="block text-sm font-medium text-gray-700 mt-2">Quantity of Shares <span class="text-red-500">*</span></label>
|
||||||
@@ -160,7 +161,7 @@
|
|||||||
type="number"
|
type="number"
|
||||||
name="quantity"
|
name="quantity"
|
||||||
value="<%= asset.quantity %>"
|
value="<%= asset.quantity %>"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
||||||
>
|
>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
@@ -173,7 +174,7 @@
|
|||||||
name="description"
|
name="description"
|
||||||
rows="4"
|
rows="4"
|
||||||
cols="50"
|
cols="50"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
||||||
><%= asset.description %></textarea>
|
><%= asset.description %></textarea>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
@@ -185,7 +186,7 @@
|
|||||||
type="date"
|
type="date"
|
||||||
name="purchaseDate"
|
name="purchaseDate"
|
||||||
value="<%= asset.purchaseDate %>"
|
value="<%= asset.purchaseDate %>"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
||||||
>
|
>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
@@ -199,7 +200,7 @@
|
|||||||
id="save-<%= asset._id %>"
|
id="save-<%= asset._id %>"
|
||||||
disabled
|
disabled
|
||||||
type="submit"
|
type="submit"
|
||||||
class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 cursor-not-allowed"
|
class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 cursor-not-allowed"
|
||||||
>
|
>
|
||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- Clickable asset list item -->
|
<!-- Clickable asset list item -->
|
||||||
<div class="mt-4 max-w-md mx-auto bg-white rounded-lg shadow-md">
|
<div class="mt-4 max-w-md mx-auto bg-white rounded-lg shadow-md <%= asset.type %>-asset">
|
||||||
<button
|
<button
|
||||||
onclick="document.getElementById('<%= asset._id %>-modal').showModal()"
|
onclick="document.getElementById('<%= asset._id %>-modal').showModal()"
|
||||||
style="width: 100%; height: 100%;"
|
style="width: 100%; height: 100%;"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<button
|
<button
|
||||||
onclick="resetAll()"
|
onclick="resetAll()"
|
||||||
type="submit"
|
type="submit"
|
||||||
class="text-center py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 cursor-pointer"
|
class="text-center py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none cursor-pointer"
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
type="radio"
|
type="radio"
|
||||||
name="type"
|
name="type"
|
||||||
value="other"
|
value="other"
|
||||||
class="form-radio h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500 cursor-pointer"
|
class="form-radio h-4 w-4 text-blue-600 border-gray-300 focus:ring-blue-500 cursor-pointer"
|
||||||
>
|
>
|
||||||
<span class="ml-2 text-sm text-gray-700">Other Assets</span>
|
<span class="ml-2 text-sm text-gray-700">Other Assets</span>
|
||||||
</label>
|
</label>
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
type="radio"
|
type="radio"
|
||||||
name="type"
|
name="type"
|
||||||
value="saving"
|
value="saving"
|
||||||
class="form-radio h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500 cursor-pointer"
|
class="form-radio h-4 w-4 text-blue-600 border-gray-300 focus:ring-blue-500 cursor-pointer"
|
||||||
>
|
>
|
||||||
<span class="ml-2 text-sm text-gray-700">Savings</span>
|
<span class="ml-2 text-sm text-gray-700">Savings</span>
|
||||||
</label>
|
</label>
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
type="radio"
|
type="radio"
|
||||||
name="type"
|
name="type"
|
||||||
value="stock"
|
value="stock"
|
||||||
class="form-radio h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500 cursor-pointer"
|
class="form-radio h-4 w-4 text-blue-600 border-gray-300 focus:ring-blue-500 cursor-pointer"
|
||||||
>
|
>
|
||||||
<span class="ml-2 text-sm text-gray-700">Stocks</span>
|
<span class="ml-2 text-sm text-gray-700">Stocks</span>
|
||||||
</label>
|
</label>
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
<button
|
<button
|
||||||
id="dropdown-icon-button"
|
id="dropdown-icon-button"
|
||||||
data-dropdown-toggle="dropdown-icons"
|
data-dropdown-toggle="dropdown-icons"
|
||||||
class="shrink-0 z-10 inline-flex items-center py-2.5 px-4 text-sm font-medium text-center border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
class="shrink-0 z-10 inline-flex items-center py-2.5 px-4 text-sm font-medium text-center border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<img src="/static/svgs/icons/Other.svg" class="h-4 w-4 me-2" alt="Other"> Other
|
<img src="/static/svgs/icons/Other.svg" class="h-4 w-4 me-2" alt="Other"> Other
|
||||||
@@ -101,10 +101,10 @@
|
|||||||
name="name"
|
name="name"
|
||||||
minlength="3"
|
minlength="3"
|
||||||
maxlength="30"
|
maxlength="30"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||||
>
|
>
|
||||||
|
|
||||||
<div id="year-create">
|
<div style="display: none;" id="year-create">
|
||||||
<label for="year" class="block text-sm font-medium text-gray-700 mt-2">Year <span class="text-red-500">*</span></label>
|
<label for="year" class="block text-sm font-medium text-gray-700 mt-2">Year <span class="text-red-500">*</span></label>
|
||||||
<input
|
<input
|
||||||
id="year-input"
|
id="year-input"
|
||||||
@@ -115,7 +115,7 @@
|
|||||||
max="<% new Date().getFullYear() %>"
|
max="<% new Date().getFullYear() %>"
|
||||||
type="number"
|
type="number"
|
||||||
name="year"
|
name="year"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@
|
|||||||
id="value"
|
id="value"
|
||||||
type="number"
|
type="number"
|
||||||
name="value"
|
name="value"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||||
>
|
>
|
||||||
|
|
||||||
<label for="purchaseDate" class="block text-sm font-medium text-gray-700 mt-2">Date of Purchase <span class="text-red-500">*</span></label>
|
<label for="purchaseDate" class="block text-sm font-medium text-gray-700 mt-2">Date of Purchase <span class="text-red-500">*</span></label>
|
||||||
@@ -137,7 +137,7 @@
|
|||||||
type="date"
|
type="date"
|
||||||
id="purchaseDate"
|
id="purchaseDate"
|
||||||
name="purchaseDate"
|
name="purchaseDate"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||||
>
|
>
|
||||||
|
|
||||||
<label for="description" class="block text-sm font-medium text-gray-700 mt-2">Description</label>
|
<label for="description" class="block text-sm font-medium text-gray-700 mt-2">Description</label>
|
||||||
@@ -147,20 +147,20 @@
|
|||||||
name="description"
|
name="description"
|
||||||
rows="4"
|
rows="4"
|
||||||
cols="50"
|
cols="50"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||||
></textarea>
|
></textarea>
|
||||||
|
|
||||||
<div class="mt-6 flex flex-row justify-between">
|
<div class="mt-6 flex flex-row justify-between">
|
||||||
<button
|
<button
|
||||||
type="reset"
|
type="reset"
|
||||||
onclick="document.getElementById('create-other-asset-form').reset()"
|
onclick="document.getElementById('create-other-asset-form').reset()"
|
||||||
class="text-center w-sm py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 cursor-pointer"
|
class="text-center w-sm py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 cursor-pointer"
|
||||||
>
|
>
|
||||||
Clear
|
Clear
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="text-center w-sm py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 cursor-pointer"
|
class="text-center w-sm py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 cursor-pointer"
|
||||||
>
|
>
|
||||||
Create
|
Create
|
||||||
</button>
|
</button>
|
||||||
@@ -179,7 +179,7 @@
|
|||||||
name="name"
|
name="name"
|
||||||
minlength="3"
|
minlength="3"
|
||||||
maxlength="30"
|
maxlength="30"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||||
>
|
>
|
||||||
|
|
||||||
<label for="value" class="block text-sm font-medium text-gray-700 mt-2">Savings Value <span class="text-red-500">*</span></label>
|
<label for="value" class="block text-sm font-medium text-gray-700 mt-2">Savings Value <span class="text-red-500">*</span></label>
|
||||||
@@ -191,20 +191,20 @@
|
|||||||
id="value"
|
id="value"
|
||||||
type="number"
|
type="number"
|
||||||
name="value"
|
name="value"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||||
>
|
>
|
||||||
|
|
||||||
<div class="mt-6 flex flex-row justify-between">
|
<div class="mt-6 flex flex-row justify-between">
|
||||||
<button
|
<button
|
||||||
type="reset"
|
type="reset"
|
||||||
onclick="document.getElementById('create-saving-asset-form').reset()"
|
onclick="document.getElementById('create-saving-asset-form').reset()"
|
||||||
class="text-center w-sm py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 cursor-pointer"
|
class="text-center w-sm py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 cursor-pointer"
|
||||||
>
|
>
|
||||||
Clear
|
Clear
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="text-center w-sm py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 cursor-pointer"
|
class="text-center w-sm py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 cursor-pointer"
|
||||||
>
|
>
|
||||||
Create
|
Create
|
||||||
</button>
|
</button>
|
||||||
@@ -223,7 +223,7 @@
|
|||||||
name="ticker"
|
name="ticker"
|
||||||
minlength="3"
|
minlength="3"
|
||||||
maxlength="5"
|
maxlength="5"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||||
>
|
>
|
||||||
|
|
||||||
<label for="price" class="block text-sm font-medium text-gray-700 mt-2">Price per Share <span class="text-red-500">*</span></label>
|
<label for="price" class="block text-sm font-medium text-gray-700 mt-2">Price per Share <span class="text-red-500">*</span></label>
|
||||||
@@ -235,7 +235,7 @@
|
|||||||
id="price"
|
id="price"
|
||||||
type="number"
|
type="number"
|
||||||
name="price"
|
name="price"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||||
>
|
>
|
||||||
|
|
||||||
<label for="quantity" class="block text-sm font-medium text-gray-700 mt-2">Quantity of Shares <span class="text-red-500">*</span></label>
|
<label for="quantity" class="block text-sm font-medium text-gray-700 mt-2">Quantity of Shares <span class="text-red-500">*</span></label>
|
||||||
@@ -245,7 +245,7 @@
|
|||||||
min="1"
|
min="1"
|
||||||
id="quantity"
|
id="quantity"
|
||||||
name="quantity"
|
name="quantity"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||||
>
|
>
|
||||||
|
|
||||||
<label for="purchaseDate" class="block text-sm font-medium text-gray-700 mt-2">Date of Purchase <span class="text-red-500">*</span></label>
|
<label for="purchaseDate" class="block text-sm font-medium text-gray-700 mt-2">Date of Purchase <span class="text-red-500">*</span></label>
|
||||||
@@ -254,20 +254,20 @@
|
|||||||
type="date"
|
type="date"
|
||||||
id="purchaseDate"
|
id="purchaseDate"
|
||||||
name="purchaseDate"
|
name="purchaseDate"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
|
||||||
>
|
>
|
||||||
|
|
||||||
<div class="mt-6 flex flex-row justify-between">
|
<div class="mt-6 flex flex-row justify-between">
|
||||||
<button
|
<button
|
||||||
type="reset"
|
type="reset"
|
||||||
onclick="document.getElementById('create-stock-asset-form').reset()"
|
onclick="document.getElementById('create-stock-asset-form').reset()"
|
||||||
class="text-center w-sm py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 cursor-pointer"
|
class="text-center w-sm py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 cursor-pointer"
|
||||||
>
|
>
|
||||||
Clear
|
Clear
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="text-center w-sm py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 cursor-pointer"
|
class="text-center w-sm py-2 mx-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 cursor-pointer"
|
||||||
>
|
>
|
||||||
Create
|
Create
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -87,10 +87,10 @@
|
|||||||
<li>
|
<li>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<button class="flex flex-row text-white hover:bg-blue-700 focus:ring-4 font-medium rounded-full text-sm focus:outline-none focus:ring-blue-800" type="button" id="drawer-toggle" data-drawer-target="drawer-navigation" data-drawer-placement="right" aria-controls="drawer-navigation">
|
<button class="flex flex-row text-white hover:bg-blue-700 focus:ring-4 font-medium rounded-full text-sm focus:outline-none focus:ring-blue-800" type="button" id="drawer-toggle" data-drawer-target="drawer-navigation" data-drawer-placement="right" aria-controls="drawer-navigation">
|
||||||
<svg class="w-[30px] h-[30px] text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 24 24">
|
<svg class="w-[30px] h-[30px] text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="white" viewBox="0 0 24 24">
|
||||||
<path fill-rule="evenodd" d="M12 20a7.966 7.966 0 0 1-5.002-1.756l.002.001v-.683c0-1.794 1.492-3.25 3.333-3.25h3.334c1.84 0 3.333 1.456 3.333 3.25v.683A7.966 7.966 0 0 1 12 20ZM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10c0 5.5-4.44 9.963-9.932 10h-.138C6.438 21.962 2 17.5 2 12Zm10-5c-1.84 0-3.333 1.455-3.333 3.25S10.159 13.5 12 13.5c1.84 0 3.333-1.455 3.333-3.25S13.841 7 12 7Z" clip-rule="evenodd"/>
|
<path fill-rule="evenodd" d="M12 20a7.966 7.966 0 0 1-5.002-1.756l.002.001v-.683c0-1.794 1.492-3.25 3.333-3.25h3.334c1.84 0 3.333 1.456 3.333 3.25v.683A7.966 7.966 0 0 1 12 20ZM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10c0 5.5-4.44 9.963-9.932 10h-.138C6.438 21.962 2 17.5 2 12Zm10-5c-1.84 0-3.333 1.455-3.333 3.25S10.159 13.5 12 13.5c1.84 0 3.333-1.455 3.333-3.25S13.841 7 12 7Z" clip-rule="evenodd"/>
|
||||||
</svg>
|
</svg>
|
||||||
<svg class="w-[30px] h-[30px] text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
|
<svg class="w-[30px] h-[30px] text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="white" viewBox="0 0 24 24">
|
||||||
<path stroke="currentColor" stroke-linecap="round" stroke-width="2" d="M5 7h14M5 12h14M5 17h14"/>
|
<path stroke="currentColor" stroke-linecap="round" stroke-width="2" d="M5 7h14M5 12h14M5 17h14"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-center space-x-2">
|
<div class="flex items-center justify-center space-x-2">
|
||||||
<button type="button" class="py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 cursor-pointer" onclick="editPlan('<%= plan._id %>')">Edit Plan</button>
|
<button type="button" class="py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 cursor-pointer" onclick="editPlan('<%= plan._id %>')">Edit Plan</button>
|
||||||
<button type="button" class="py-2 px-4 border border-red-600 rounded-md shadow-sm text-sm font-medium text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 cursor-pointer" onclick="deletePlan('<%= plan._id %>')">Delete Plan</button>
|
<button type="button" class="py-2 px-4 border border-red-600 rounded-md shadow-sm text-sm font-medium text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 cursor-pointer" onclick="deletePlan('<%= plan._id %>')">Delete Plan</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
<div class="flex flex-row justify-between items-center">
|
<div class="flex flex-row justify-between items-center">
|
||||||
<h3 class="text-lg font-bold text-gray-900">Create New Retirement Plan</h3>
|
<h3 class="text-lg font-bold text-gray-900">Create New Retirement Plan</h3>
|
||||||
<form method="dialog" id="cancelNewPlanDialogForm">
|
<form method="dialog" id="cancelNewPlanDialogForm">
|
||||||
<button type="submit" class="py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 cursor-pointer">Cancel</button>
|
<button type="submit" class="py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 cursor-pointer">Cancel</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -34,29 +34,29 @@
|
|||||||
<p class="text-sm text-gray-400 text-left mb-4"><span class="text-red-500">*</span> Indicates a required field</p>
|
<p class="text-sm text-gray-400 text-left mb-4"><span class="text-red-500">*</span> Indicates a required field</p>
|
||||||
<div>
|
<div>
|
||||||
<label for="name" class="block text-sm font-medium text-gray-700 text-left">Plan Name <span class="text-red-500">*</span></label>
|
<label for="name" class="block text-sm font-medium text-gray-700 text-left">Plan Name <span class="text-red-500">*</span></label>
|
||||||
<input type="text" name="name" id="planName" placeholder="e.g., My Awesome Plan" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
|
<input type="text" name="name" id="planName" placeholder="e.g., My Awesome Plan" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm" required>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="retirementAge" class="block text-sm font-medium text-gray-700 text-left">Desired Retirement Age <span class="text-red-500">*</span></label>
|
<label for="retirementAge" class="block text-sm font-medium text-gray-700 text-left">Desired Retirement Age <span class="text-red-500">*</span></label>
|
||||||
<input type="number" name="retirementAge" id="retirementAge" placeholder="e.g., 65" min="18" max="120" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
|
<input type="number" name="retirementAge" id="retirementAge" placeholder="e.g., 65" min="18" max="120" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm" required>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="retirementExpenses" class="block text-sm font-medium text-gray-700 text-left">Estimated Monthly Retirement Expenses <span class="text-red-500">*</span></label>
|
<label for="retirementExpenses" class="block text-sm font-medium text-gray-700 text-left">Estimated Monthly Retirement Expenses <span class="text-red-500">*</span></label>
|
||||||
<input title="Ongoing spending. Rent, bills, subscriptions, etc." type="number" name="retirementExpenses" id="retirementExpenses" min="0" placeholder="e.g., 3000" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
|
<input title="Ongoing spending. Rent, bills, subscriptions, etc." type="number" name="retirementExpenses" id="retirementExpenses" min="0" placeholder="e.g., 3000" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm" required>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="retirementAssets" class="block text-sm font-medium text-gray-700 text-left">Estimated Retirement Assets <span class="text-red-500">*</span></label>
|
<label for="retirementAssets" class="block text-sm font-medium text-gray-700 text-left">Estimated Retirement Assets <span class="text-red-500">*</span></label>
|
||||||
<input title="Owned valuables. Physical items, investments, etc." type="number" name="retirementAssets" id="retirementAssets" min="0" placeholder="e.g., 500000" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
|
<input title="Owned valuables. Physical items, investments, etc." type="number" name="retirementAssets" id="retirementAssets" min="0" placeholder="e.g., 500000" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm" required>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="retirementLiabilities" class="block text-sm font-medium text-gray-700 text-left">Estimated Retirement Liabilities <span class="text-red-500">*</span></label>
|
<label for="retirementLiabilities" class="block text-sm font-medium text-gray-700 text-left">Estimated Retirement Liabilities <span class="text-red-500">*</span></label>
|
||||||
<input title="Owed amounts. Loans, credit card balance, etc." type="number" name="retirementLiabilities" id="retirementLiabilities" min="0" placeholder="e.g., 50000" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
|
<input title="Owed amounts. Loans, credit card balance, etc." type="number" name="retirementLiabilities" id="retirementLiabilities" min="0" placeholder="e.g., 50000" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm" required>
|
||||||
</div>
|
</div>
|
||||||
<div id="newPlanError" class="text-red-500 text-sm mt-2" style="display: none;"></div>
|
<div id="newPlanError" class="text-red-500 text-sm mt-2" style="display: none;"></div>
|
||||||
<!-- Form Buttons: Save Plan and Reset -->
|
<!-- Form Buttons: Save Plan and Reset -->
|
||||||
<div class="mt-6 flex flex-row justify-between">
|
<div class="mt-6 flex flex-row justify-between">
|
||||||
<button type="button" id="resetNewPlanFormBtn" class="py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">Reset</button>
|
<button type="button" id="resetNewPlanFormBtn" class="py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">Reset</button>
|
||||||
<button id="submitNewPlanBtn" type="submit" class="py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">Save Plan</button>
|
<button id="submitNewPlanBtn" type="submit" class="py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">Save Plan</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -51,24 +51,24 @@
|
|||||||
<div class="max-w-md mx-auto bg-white p-8 mb-10 rounded-lg shadow-md">
|
<div class="max-w-md mx-auto bg-white p-8 mb-10 rounded-lg shadow-md">
|
||||||
<div class="flex flex-row justify-between">
|
<div class="flex flex-row justify-between">
|
||||||
<h3 class="pt-2 pr-2 pb-2">Account settings</h3>
|
<h3 class="pt-2 pr-2 pb-2">Account settings</h3>
|
||||||
<button id="edit-account" onclick="unlockAccount()" class="py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">Edit</button>
|
<button id="edit-account" onclick="unlockAccount()" class="py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">Edit</button>
|
||||||
</div>
|
</div>
|
||||||
<form action="/updateAccount" method="post" class="space-y-4 mt-4" id="account-form">
|
<form action="/updateAccount" method="post" class="space-y-4 mt-4" id="account-form">
|
||||||
|
|
||||||
<label for="email" class="block text-sm font-medium text-gray-700">Email</label>
|
<label for="email" class="block text-sm font-medium text-gray-700">Email</label>
|
||||||
<input id="email" disabled type="email" name="email" value="<%= user.email %>" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
<input id="email" disabled type="email" name="email" value="<%= user.email %>" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
||||||
|
|
||||||
<label for="name" class="block text-sm font-medium text-gray-700">Name</label>
|
<label for="name" class="block text-sm font-medium text-gray-700">Name</label>
|
||||||
<input id="name" disabled type="text" name="name" value="<%= user.name %>" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
<input id="name" disabled type="text" name="name" value="<%= user.name %>" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
||||||
|
|
||||||
<label for="password" class="block text-sm font-medium text-gray-700">New password</label>
|
<label for="password" class="block text-sm font-medium text-gray-700">New password</label>
|
||||||
<input id="password" disabled type="password" name="password" minlength="8" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
<input id="password" disabled type="password" name="password" minlength="8" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
||||||
|
|
||||||
<label for="repassword" class="block text-sm font-medium text-gray-700">Confirm new password</label>
|
<label for="repassword" class="block text-sm font-medium text-gray-700">Confirm new password</label>
|
||||||
<input id="repassword" disabled type="password" name="repassword" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
<input id="repassword" disabled type="password" name="repassword" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button id="save-account" disabled type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 cursor-not-allowed">Save</button>
|
<button id="save-account" disabled type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 cursor-not-allowed">Save</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
<div class="flex flex-row justify-between">
|
<div class="flex flex-row justify-between">
|
||||||
<h3 class="pt-2 pr-2 pb-2">Personal information</h3>
|
<h3 class="pt-2 pr-2 pb-2">Personal information</h3>
|
||||||
<% if (user.financialData) { %>
|
<% if (user.financialData) { %>
|
||||||
<button id="edit-personal" onclick="unlockPersonal()" class="py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">Edit</button>
|
<button id="edit-personal" onclick="unlockPersonal()" class="py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">Edit</button>
|
||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -91,17 +91,19 @@
|
|||||||
id="dob"
|
id="dob"
|
||||||
type="date"
|
type="date"
|
||||||
name="dob"
|
name="dob"
|
||||||
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none"
|
||||||
<% let year = typeof(user.dob) == "object" ? user.dob.getFullYear() : user.dob.split('-')[0]; %>
|
<% let year = typeof(user.dob) == "object" ? user.dob.getFullYear() : user.dob.split('-')[0]; %>
|
||||||
<% let month = typeof(user.dob) == "object" ? user.dob.getMonth() : user.dob.split('-')[1] - 1; %>
|
<% let month = typeof(user.dob) == "object" ? user.dob.getMonth() : user.dob.split('-')[1] - 1; %>
|
||||||
<% let day = typeof(user.dob) == "object" ? user.dob.getDate() + 1 : user.dob.split('-')[2].split('T')[0];%>
|
<% let day = typeof(user.dob) == "object" ? user.dob.getDate() + 1 : user.dob.split('-')[2].split('T')[0];%>
|
||||||
<% let d = new Date(parseInt(year), parseInt(month), parseInt(day)); %>
|
<% let d = new Date(parseInt(year), parseInt(month), parseInt(day)); %>
|
||||||
value="<%= d.getFullYear() + "-" + ("0"+(d.getMonth()+1)).slice(-2) + "-" + ("0" + d.getDate()).slice(-2); %>"
|
value="<%= d.getFullYear() + "-" + ("0"+(d.getMonth()+1)).slice(-2) + "-" + ("0" + d.getDate()).slice(-2); %>"
|
||||||
|
<% let d1 = new Date(); %>
|
||||||
|
max="<%= (d1.getFullYear() - 18) + "-" +("0"+(d1.getMonth()+1)).slice(-2) + "-" + ("0" + d1.getDate()).slice(-2); %>"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="education" class="block text-sm font-medium text-gray-700">Education</label>
|
<label for="education" class="block text-sm font-medium text-gray-700">Education</label>
|
||||||
<select disabled id="education" name="education" id="education" class="mt-1 block w-full px-3 py-2 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
<select disabled id="education" name="education" id="education" class="mt-1 block w-full px-3 py-2 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
||||||
<option <%= user.education == "primary" ? 'selected' : '' %> value="primary">Primary (Elementary)</option>
|
<option <%= user.education == "primary" ? 'selected' : '' %> value="primary">Primary (Elementary)</option>
|
||||||
<option <%= user.education == "secondary" ? 'selected' : '' %> value="secondary">Secondary (High School)</option>
|
<option <%= user.education == "secondary" ? 'selected' : '' %> value="secondary">Secondary (High School)</option>
|
||||||
<option <%= user.education == "tertiary" ? 'selected' : '' %> value="tertiary">Tertiary (College/University)</option>
|
<option <%= user.education == "tertiary" ? 'selected' : '' %> value="tertiary">Tertiary (College/University)</option>
|
||||||
@@ -112,19 +114,19 @@
|
|||||||
<label class="block text-sm font-medium text-gray-700">Marital Status</label>
|
<label class="block text-sm font-medium text-gray-700">Marital Status</label>
|
||||||
<div class="mt-1 space-x-4">
|
<div class="mt-1 space-x-4">
|
||||||
<label class="inline-flex items-center">
|
<label class="inline-flex items-center">
|
||||||
<input disabled <%= user.maritalStatus == "single" ? 'checked' : '' %> id="ms-single" type="radio" name="maritalStatus" value="single" class="form-radio h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500 disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
<input disabled <%= user.maritalStatus == "single" ? 'checked' : '' %> id="ms-single" type="radio" name="maritalStatus" value="single" class="form-radio h-4 w-4 text-blue-600 border-gray-300 focus:ring-blue-500 disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
||||||
<span class="ml-2 text-sm text-gray-700">Single</span>
|
<span class="ml-2 text-sm text-gray-700">Single</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="inline-flex items-center">
|
<label class="inline-flex items-center">
|
||||||
<input disabled <%= user.maritalStatus == "married" ? 'checked' : '' %> id="ms-married" type="radio" name="maritalStatus" value="married" class="form-radio h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500 disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
<input disabled <%= user.maritalStatus == "married" ? 'checked' : '' %> id="ms-married" type="radio" name="maritalStatus" value="married" class="form-radio h-4 w-4 text-blue-600 border-gray-300 focus:ring-blue-500 disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
||||||
<span class="ml-2 text-sm text-gray-700">Married</span>
|
<span class="ml-2 text-sm text-gray-700">Married</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="inline-flex items-center">
|
<label class="inline-flex items-center">
|
||||||
<input disabled <%= user.maritalStatus == "divorced" ? 'checked' : '' %> id="ms-divorced" type="radio" name="maritalStatus" value="divorced" class="form-radio h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500 disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
<input disabled <%= user.maritalStatus == "divorced" ? 'checked' : '' %> id="ms-divorced" type="radio" name="maritalStatus" value="divorced" class="form-radio h-4 w-4 text-blue-600 border-gray-300 focus:ring-blue-500 disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
||||||
<span class="ml-2 text-sm text-gray-700">Divorced</span>
|
<span class="ml-2 text-sm text-gray-700">Divorced</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="inline-flex items-center">
|
<label class="inline-flex items-center">
|
||||||
<input disabled <%= user.maritalStatus == "widowed" ? 'checked' : '' %> id="ms-widowed" type="radio" name="maritalStatus" value="widowed" class="form-radio h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500 disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
<input disabled <%= user.maritalStatus == "widowed" ? 'checked' : '' %> id="ms-widowed" type="radio" name="maritalStatus" value="widowed" class="form-radio h-4 w-4 text-blue-600 border-gray-300 focus:ring-blue-500 disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
||||||
<span class="ml-2 text-sm text-gray-700">Widowed</span>
|
<span class="ml-2 text-sm text-gray-700">Widowed</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -132,31 +134,31 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="income" class="block text-sm font-medium text-gray-700">Annual Gross Income</label>
|
<label for="income" class="block text-sm font-medium text-gray-700">Annual Gross Income</label>
|
||||||
<input disabled value="<%= user.income %>" id="income" type="number" name="income" min="0" placeholder="e.g., 50000" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
<input disabled value="<%= user.income %>" id="income" type="number" name="income" min="0" placeholder="e.g., 50000" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="expenses" class="block text-sm font-medium text-gray-700">Monthly Expenses</label>
|
<label for="expenses" class="block text-sm font-medium text-gray-700">Monthly Expenses</label>
|
||||||
<input disabled value="<%= user.expenses %>" id="expenses" type="number" name="expenses" min="0" placeholder="e.g., 2000" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
<input disabled value="<%= user.expenses %>" id="expenses" type="number" name="expenses" min="0" placeholder="e.g., 2000" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="assets" class="block text-sm font-medium text-gray-700">Net Worth</label>
|
<label for="assets" class="block text-sm font-medium text-gray-700">Net Worth</label>
|
||||||
<input disabled value="<%= user.assets %>" id="assets" type="number" name="assets" min="0" placeholder="Estimated Net Worth" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
<input disabled value="<%= user.assets %>" id="assets" type="number" name="assets" min="0" placeholder="Estimated Net Worth" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="liabilities" class="block text-sm font-medium text-gray-700">Liabilities</label>
|
<label for="liabilities" class="block text-sm font-medium text-gray-700">Liabilities</label>
|
||||||
<input disabled value="<%= user.liabilities %>" id="liabilities" type="number" name="liabilities" min="0" placeholder="Estimated Liabilities" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
<input disabled value="<%= user.liabilities %>" id="liabilities" type="number" name="liabilities" min="0" placeholder="Estimated Liabilities" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button id="save-personal" disabled type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 cursor-not-allowed">Save</button>
|
<button id="save-personal" disabled type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 cursor-not-allowed">Save</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
<div>
|
<div>
|
||||||
<a href="/questionnaire?profile" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 cursor-pointer">Answer Questionnare</a>
|
<a href="/questionnaire?profile" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 cursor-pointer">Answer Questionnare</a>
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,12 @@
|
|||||||
<form action="/questionnaire" method="post" class="space-y-4">
|
<form action="/questionnaire" method="post" class="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label for="dob" class="block text-sm font-medium text-gray-700">Date of Birth <span class="text-red-500">*</span></label>
|
<label for="dob" class="block text-sm font-medium text-gray-700">Date of Birth <span class="text-red-500">*</span></label>
|
||||||
<input type="date" name="dob" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
<% let d = new Date(); %>
|
||||||
|
<input max="<%= (d.getFullYear() - 18) + "-" + ("0"+(d.getMonth()+1)).slice(-2) + "-" + ("0" + d.getDate()).slice(-2); %>" type="date" name="dob" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="education" class="block text-sm font-medium text-gray-700">Education <span class="text-red-500">*</span></label>
|
<label for="education" class="block text-sm font-medium text-gray-700">Education <span class="text-red-500">*</span></label>
|
||||||
<select name="education" id="education" class="mt-1 block w-full px-3 py-2 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
<select name="education" id="education" class="mt-1 block w-full px-3 py-2 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
|
||||||
<option value="primary">Primary (Elementary)</option>
|
<option value="primary">Primary (Elementary)</option>
|
||||||
<option value="secondary">Secondary (High School)</option>
|
<option value="secondary">Secondary (High School)</option>
|
||||||
<option value="tertiary">Tertiary (College/University)</option>
|
<option value="tertiary">Tertiary (College/University)</option>
|
||||||
@@ -23,19 +24,19 @@
|
|||||||
<label class="block text-sm font-medium text-gray-700">Marital Status <span class="text-red-500">*</span></label>
|
<label class="block text-sm font-medium text-gray-700">Marital Status <span class="text-red-500">*</span></label>
|
||||||
<div class="mt-1 space-x-4">
|
<div class="mt-1 space-x-4">
|
||||||
<label class="inline-flex items-center">
|
<label class="inline-flex items-center">
|
||||||
<input type="radio" name="maritalStatus" value="single" class="form-radio h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500">
|
<input type="radio" name="maritalStatus" value="single" class="form-radio h-4 w-4 text-blue-600 border-gray-300 focus:ring-blue-500">
|
||||||
<span class="ml-2 text-sm text-gray-700">Single</span>
|
<span class="ml-2 text-sm text-gray-700">Single</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="inline-flex items-center">
|
<label class="inline-flex items-center">
|
||||||
<input type="radio" name="maritalStatus" value="married" class="form-radio h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500">
|
<input type="radio" name="maritalStatus" value="married" class="form-radio h-4 w-4 text-blue-600 border-gray-300 focus:ring-blue-500">
|
||||||
<span class="ml-2 text-sm text-gray-700">Married</span>
|
<span class="ml-2 text-sm text-gray-700">Married</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="inline-flex items-center">
|
<label class="inline-flex items-center">
|
||||||
<input type="radio" name="maritalStatus" value="divorced" class="form-radio h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500">
|
<input type="radio" name="maritalStatus" value="divorced" class="form-radio h-4 w-4 text-blue-600 border-gray-300 focus:ring-blue-500">
|
||||||
<span class="ml-2 text-sm text-gray-700">Divorced</span>
|
<span class="ml-2 text-sm text-gray-700">Divorced</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="inline-flex items-center">
|
<label class="inline-flex items-center">
|
||||||
<input type="radio" name="maritalStatus" value="widowed" class="form-radio h-4 w-4 text-indigo-600 border-gray-300 focus:ring-indigo-500">
|
<input type="radio" name="maritalStatus" value="widowed" class="form-radio h-4 w-4 text-blue-600 border-gray-300 focus:ring-blue-500">
|
||||||
<span class="ml-2 text-sm text-gray-700">Widowed</span>
|
<span class="ml-2 text-sm text-gray-700">Widowed</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -43,26 +44,26 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="income" class="block text-sm font-medium text-gray-700">Annual Gross Income <span class="text-red-500">*</span></label>
|
<label for="income" class="block text-sm font-medium text-gray-700">Annual Gross Income <span class="text-red-500">*</span></label>
|
||||||
<input type="number" name="income" min="0" placeholder="e.g., 50000" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
<input type="number" name="income" min="0" placeholder="e.g., 50000" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="expenses" class="block text-sm font-medium text-gray-700">Monthly Expenses <span class="text-red-500">*</span></label>
|
<label for="expenses" class="block text-sm font-medium text-gray-700">Monthly Expenses <span class="text-red-500">*</span></label>
|
||||||
<input type="number" name="expenses" min="0" placeholder="e.g., 2000" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
<input type="number" name="expenses" min="0" placeholder="e.g., 2000" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="assets" class="block text-sm font-medium text-gray-700">Net Worth <span class="text-red-500">*</span></label>
|
<label for="assets" class="block text-sm font-medium text-gray-700">Net Worth <span class="text-red-500">*</span></label>
|
||||||
<input type="number" name="assets" min="0" placeholder="Estimated Net Worth" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
<input type="number" name="assets" min="0" placeholder="Estimated Net Worth" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="liabilities" class="block text-sm font-medium text-gray-700">Liabilities <span class="text-red-500">*</span></label>
|
<label for="liabilities" class="block text-sm font-medium text-gray-700">Liabilities <span class="text-red-500">*</span></label>
|
||||||
<input type="number" name="liabilities" min="0" placeholder="Estimated Liabilities" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
<input type="number" name="liabilities" min="0" placeholder="Estimated Liabilities" class="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">Submit Questionnaire</button>
|
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">Submit Questionnaire</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
<% } %>
|
<% } %>
|
||||||
<div class="mt-5">
|
<div class="mt-5">
|
||||||
<button type="submit"
|
<button type="submit"
|
||||||
class="cursor-pointer border-2 border-gray-600 bg-blue-600 text-white py-1 w-full rounded-md hover:bg-transparent hover:text-indigo-700 font-semibold">Change
|
class="cursor-pointer border-2 border-gray-600 bg-blue-600 text-white py-1 w-full rounded-md hover:bg-transparent hover:text-blue-700 font-semibold">Change
|
||||||
Password</button>
|
Password</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,23 +11,23 @@
|
|||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<label for="name" class="block text-base mb-2 text-slate-600">Name <span class="text-red-500">*</span></label>
|
<label for="name" class="block text-base mb-2 text-slate-600">Name <span class="text-red-500">*</span></label>
|
||||||
<input required type="text" id="name" name="name"
|
<input required type="text" id="name" name="name"
|
||||||
class="border border-slate-300 focus:border-indigo-500 w-full rounded-md text-base px-3 py-2 focus:outline-none focus:ring-1 focus:ring-indigo-500 transition-colors duration-200"
|
class="border border-slate-300 focus:border-blue-500 w-full rounded-md text-base px-3 py-2 focus:outline-none focus:ring-1 focus:ring-blue-500 transition-colors duration-200"
|
||||||
placeholder="Enter Name" value="<%= typeof name != 'undefined' ? name : '' %>"/>
|
placeholder="Enter Name" value="<%= typeof name != 'undefined' ? name : '' %>"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<label for="email" class="block text-base mb-2 text-slate-600">Email <span class="text-red-500">*</span></label>
|
<label for="email" class="block text-base mb-2 text-slate-600">Email <span class="text-red-500">*</span></label>
|
||||||
<input required type="email" id="email" name="email"
|
<input required type="email" id="email" name="email"
|
||||||
class="border border-slate-300 focus:border-indigo-500 w-full rounded-md text-base px-3 py-2 focus:outline-none focus:ring-1 focus:ring-indigo-500 transition-colors duration-200"
|
class="border border-slate-300 focus:border-blue-500 w-full rounded-md text-base px-3 py-2 focus:outline-none focus:ring-1 focus:ring-blue-500 transition-colors duration-200"
|
||||||
placeholder="Enter Email" value="<%= typeof email != 'undefined' ? email : '' %>"/>
|
placeholder="Enter Email" value="<%= typeof email != 'undefined' ? email : '' %>"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<label for="password" class="block text-base mb-2 text-slate-600">Password <span class="text-red-500">*</span></label>
|
<label for="password" class="block text-base mb-2 text-slate-600">Password <span class="text-red-500">*</span></label>
|
||||||
<input required type="password" id="password" name="password"
|
<input required type="password" id="password" name="password"
|
||||||
class="border border-slate-300 focus:border-indigo-500 w-full rounded-md text-base px-3 py-2 focus:outline-none focus:ring-1 focus:ring-indigo-500 transition-colors duration-200"
|
class="border border-slate-300 focus:border-blue-500 w-full rounded-md text-base px-3 py-2 focus:outline-none focus:ring-1 focus:ring-blue-500 transition-colors duration-200"
|
||||||
placeholder="Enter Password" />
|
placeholder="Enter Password" />
|
||||||
<label for="repassword" class="block text-base mb-2 mt-3 text-slate-600">Re-type Password <span class="text-red-500">*</span></label>
|
<label for="repassword" class="block text-base mb-2 mt-3 text-slate-600">Re-type Password <span class="text-red-500">*</span></label>
|
||||||
<input required type="password" id="repassword" name="repassword"
|
<input required type="password" id="repassword" name="repassword"
|
||||||
class="border border-slate-300 focus:border-indigo-500 w-full rounded-md text-base px-3 py-2 focus:outline-none focus:ring-1 focus:ring-indigo-500 transition-colors duration-200"
|
class="border border-slate-300 focus:border-blue-500 w-full rounded-md text-base px-3 py-2 focus:outline-none focus:ring-1 focus:ring-blue-500 transition-colors duration-200"
|
||||||
placeholder="Enter Password" />
|
placeholder="Enter Password" />
|
||||||
</div>
|
</div>
|
||||||
<% if (errMessage && errMessage.length > 0) { %>
|
<% if (errMessage && errMessage.length > 0) { %>
|
||||||
@@ -37,11 +37,11 @@
|
|||||||
<% } %>
|
<% } %>
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
<button type="submit"
|
<button type="submit"
|
||||||
class="border-2 border-indigo-600 bg-indigo-600 text-white py-2 w-full rounded-md hover:bg-indigo-700 hover:border-indigo-700 font-semibold transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">Signup</button>
|
class="border-2 border-blue-600 bg-blue-600 text-white py-2 w-full rounded-md hover:bg-blue-700 hover:border-blue-700 font-semibold transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">Signup</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-6 text-center">
|
<div class="mt-6 text-center">
|
||||||
<span class="text-sm text-slate-600">Already have an account?</span>
|
<span class="text-sm text-slate-600">Already have an account?</span>
|
||||||
<a href="/login" class="text-sm text-indigo-600 hover:text-indigo-500 font-semibold ml-1 transition-colors duration-200">Login</a>
|
<a href="/login" class="text-sm text-blue-600 hover:text-blue-500 font-semibold ml-1 transition-colors duration-200">Login</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||