Compare commits
2 Commits
5668d767e2
...
acfadce5cb
Author | SHA1 | Date |
---|---|---|
Ron Reciproco | acfadce5cb | 1 year ago |
Ron Reciproco | e3ea0503bc | 1 year ago |
@ -0,0 +1,98 @@
|
||||
S21 Notes:
|
||||
|
||||
Functions: Functions are blocks of reusable code that perform a specific task. They take input, process it, and return an output.
|
||||
|
||||
Function Declaration: A function declaration is a way to define a function in JavaScript using the `function` keyword followed by the function's name and parameters.
|
||||
|
||||
Function Invocation: Function invocation means calling or executing a function to perform its defined task.
|
||||
|
||||
Differences between function declaration vs function expression: Function declaration is hoisted (i.e., can be called before it's defined) and has a named identifier, while function expression is not hoisted and can be anonymous or have a name.
|
||||
|
||||
Function scoping: Function scoping refers to the concept that variables defined within a function are only accessible within that function and are not visible in the outer scope.
|
||||
|
||||
Function scope: Function scope is the area within a function where a variable can be accessed. Variables defined inside a function have function scope and are not visible outside of it.
|
||||
|
||||
Return statement: The return statement is used in a function to specify the value that should be outputted by the function when it is called.
|
||||
|
||||
Importance of return statement: The return statement is crucial because it allows a function to produce an output that can be used in other parts of a program. It's how a function communicates its result to the code that called it.
|
||||
|
||||
S22 Notes:
|
||||
|
||||
|
||||
Parameters: Parameters are variables listed in the function definition. They act as placeholders for values that the function will receive when it is called.
|
||||
|
||||
Arguments: Arguments are the actual values that are passed to a function when it is called. They correspond to the parameters defined in the function declaration.
|
||||
|
||||
Functions as Arguments: This refers to the concept of passing a function as a value to another function. This allows for dynamic behavior and is a powerful feature in JavaScript.
|
||||
|
||||
Invoking functions: Invoking a function means calling or executing the function to perform its defined task. This is done by using the function's name followed by parentheses, and providing any required arguments.
|
||||
|
||||
|
||||
S23 Notes:
|
||||
|
||||
console.warn: In JavaScript, console.warn is a method that allows you to log warning messages to the console. It's often used to indicate potential issues or non-critical problems in your code.
|
||||
|
||||
if statement: The if statement is a control flow structure that allows you to execute a block of code if a specified condition evaluates to true. If the condition is false, the code block is skipped.
|
||||
|
||||
if-else statement: The if-else statement is an extension of the if statement. It provides an alternative code block to execute if the initial condition evaluates to false.
|
||||
|
||||
else-if clause: The else-if clause allows you to specify additional conditions to be checked if the previous if or else-if conditions are false. It's used in conjunction with the if-else statement.
|
||||
|
||||
else statement: The else statement is used in conjunction with an if statement to specify a block of code to execute if the condition evaluates to false.
|
||||
|
||||
Truthy value: A truthy value is a value that is considered true when encountered in a Boolean context. This includes non-empty strings, non-zero numbers, and objects.
|
||||
|
||||
Falsy value: A falsy value is a value that is considered false when encountered in a Boolean context. This includes false, 0, null, undefined, NaN, and an empty string ('').
|
||||
|
||||
Conditional Ternary Operator: The conditional (ternary) operator is a concise way to write an if-else statement in a single line of code. It takes the form condition ? expressionIfTrue : expressionIfFalse.
|
||||
|
||||
Switch statement: The switch statement is used to select one of many code blocks to be executed. It evaluates an expression and executes the corresponding case.
|
||||
|
||||
Try-Catch-Finally statement: The try-catch-finally statement is used for exception handling in JavaScript. The try block contains the code that might throw an exception, the catch block handles the exception, and the finally block is executed regardless of whether an exception was thrown or caught.
|
||||
|
||||
S24 Notes:
|
||||
|
||||
|
||||
While loop: A while loop is a control flow statement that allows a block of code to be executed repeatedly as long as a specified condition is true.
|
||||
|
||||
Expressions/Conditions: In JavaScript, expressions are pieces of code that produce a value. Conditions are expressions that can be evaluated as true or false.
|
||||
|
||||
Statement: A statement is a single line of code or a group of lines that perform a specific action. In JavaScript, statements can be things like variable declarations, loops, or function calls.
|
||||
|
||||
Increment: Incrementing means increasing the value of a variable by a certain amount, typically by 1.
|
||||
|
||||
Decrement: Decrementing means decreasing the value of a variable by a certain amount, typically by 1.
|
||||
|
||||
Do while loop: Similar to a while loop, a do-while loop executes a block of code repeatedly, but it checks the condition at the end of the loop, so the code inside the loop is executed at least once.
|
||||
|
||||
Prompt: prompt is a method in JavaScript that displays a dialog box to the user, prompting them to input some data. It's commonly used in web development for getting user input.
|
||||
|
||||
typeof: typeof is an operator in JavaScript that allows you to determine the data type of a value or expression.
|
||||
|
||||
For loop: A for loop is a control flow statement that allows code to be executed repeatedly for a specific number of times. It consists of an initialization, a condition, and an iteration.
|
||||
|
||||
Initialization: Initialization is the step in a loop where you set the initial value of a variable that controls the loop.
|
||||
|
||||
Final Expression: The final expression is the condition that is evaluated at the end of each iteration of a loop. If this condition is true, the loop continues; if false, the loop ends.
|
||||
|
||||
.toLowerCase: .toLowerCase is a method in JavaScript that converts a string to lowercase letters. For example, it would convert "HELLO" to "hello".
|
||||
|
||||
|
||||
S25 Notes:
|
||||
|
||||
Objects: In JavaScript, an object is a collection of key-value pairs, where each key is a string (or Symbol) and each value can be any data type.
|
||||
|
||||
Key-pairs: In an object, a key-value pair consists of a key (a unique identifier) and its corresponding value.
|
||||
|
||||
Constructor function: A constructor function in JavaScript is a blueprint for creating objects. It's used to define a type of object and how it should be initialized.
|
||||
|
||||
"this" keyword: The this keyword in JavaScript refers to the object that is currently executing the function. It allows a function to access and work with its own object.
|
||||
|
||||
"new" operator: The new operator is used to create an instance of a user-defined object type or one of the built-in object types in JavaScript.
|
||||
|
||||
Dot notation: Dot notation is a way to access properties and methods of an object by using a dot (.) followed by the property or method name.
|
||||
|
||||
Square bracket notation: Square bracket notation is an alternative way to access properties and methods of an object by using square brackets [] and passing in a string containing the property or method name.
|
||||
|
||||
Object methods: Object methods are functions that are stored as properties within an object. They can be called and executed just like any other function, but they are associated with a specific object and can access its properties.
|
||||
|
@ -0,0 +1 @@
|
||||
Subproject commit 7349309dae7fbdf2b9abd8e2b13027eac949d54a
|
@ -0,0 +1,3 @@
|
||||
PORT = 3000
|
||||
MONGO_URL = mongodb+srv://ronreciproco123:admin123@capstone-2.5mwo2wg.mongodb.net/CSP2
|
||||
SECRET_SAUCE = cornhub
|
@ -0,0 +1 @@
|
||||
node_modules
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"tabWidth": 4,
|
||||
"useTabs": true,
|
||||
"semi": false,
|
||||
"trailingComma": "es5"
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
const jwt = require('jsonwebtoken');
|
||||
require("dotenv").config()
|
||||
|
||||
// Function to verify JWT token
|
||||
exports.verifyToken = (token) => {
|
||||
try {
|
||||
const decoded = jwt.verify(token, process.env.SECRET_SAUCE);
|
||||
return decoded;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return null; // Return null if verification fails
|
||||
}
|
||||
};
|
||||
|
||||
// Middleware for verifying JWT token
|
||||
exports.authenticateToken = (req, res, next) => {
|
||||
// Extract the token from the Authorization header
|
||||
const token = req.header('Authorization')?.replace('Bearer ', '');
|
||||
|
||||
if (!token) {
|
||||
return res.status(401).json({ message: 'Unauthorized. Token not provided.' });
|
||||
}
|
||||
|
||||
const decoded = exports.verifyToken(token);
|
||||
|
||||
if (!decoded) {
|
||||
return res.status(401).json({ message: 'Unauthorized. Invalid token.' });
|
||||
}
|
||||
|
||||
// Attach the decoded information to the request for future use
|
||||
req.user = decoded;
|
||||
|
||||
// Proceed to the next middleware or route handler
|
||||
next();
|
||||
};
|
||||
|
||||
// Function to generate a JWT token
|
||||
exports.generateToken = (userId, email) => {
|
||||
return jwt.sign({ userId, email }, process.env.SECRET_SAUCE, { expiresIn: '1h' });
|
||||
};
|
@ -0,0 +1,52 @@
|
||||
// productController.js
|
||||
const Product = require('../model/Product');
|
||||
|
||||
// Controller function for creating a product (accessible only by isAdmin)
|
||||
exports.createProduct = async (req, res) => {
|
||||
try {
|
||||
// Check if the user is an admin
|
||||
if (!req.user.isAdmin) {
|
||||
return res.status(403).json({ message: 'Permission denied. Only admins can create products.' });
|
||||
}
|
||||
|
||||
const { name, description, price, isActive } = req.body;
|
||||
|
||||
const newProduct = new Product({
|
||||
name,
|
||||
description,
|
||||
price,
|
||||
isActive,
|
||||
});
|
||||
|
||||
await newProduct.save();
|
||||
|
||||
res.status(201).json({ message: 'Product created successfully' });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ message: 'Internal server error' });
|
||||
}
|
||||
};
|
||||
|
||||
// Controller function for retrieving all products (accessible to both admin and normal user)
|
||||
exports.getAllProducts = async (req, res) => {
|
||||
try {
|
||||
const products = await Product.find();
|
||||
|
||||
res.status(200).json(products);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ message: 'Internal server error' });
|
||||
}
|
||||
};
|
||||
|
||||
// Controller function for retrieving all active products (accessible to both admin and normal user)
|
||||
exports.getActiveProducts = async (req, res) => {
|
||||
try {
|
||||
const activeProducts = await Product.find({ isActive: true });
|
||||
|
||||
res.status(200).json(activeProducts);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ message: 'Internal server error' });
|
||||
}
|
||||
};
|
@ -0,0 +1,124 @@
|
||||
const bcrypt = require("bcrypt")
|
||||
const faker = require("faker")
|
||||
const User = require("../model/User")
|
||||
const auth = require("../auth")
|
||||
|
||||
// Controller function for user registration
|
||||
exports.registerUser = async (req, res) => {
|
||||
try {
|
||||
const { email, password, firstName, lastName } = req.body;
|
||||
|
||||
// If firstName and lastName are not provided, generate default values using faker
|
||||
const autoGeneratedFirstName = firstName || faker.name.firstName();
|
||||
const autoGeneratedLastName = lastName || faker.name.lastName();
|
||||
|
||||
// Hash the password before saving it
|
||||
const hashedPassword = await bcrypt.hash(password, 10);
|
||||
|
||||
const newUser = new User({
|
||||
email,
|
||||
password: hashedPassword,
|
||||
firstName: autoGeneratedFirstName,
|
||||
lastName: autoGeneratedLastName,
|
||||
});
|
||||
|
||||
await newUser.save();
|
||||
|
||||
res.status(201).json({ message: 'User registered successfully. To update account details, acess user/update' });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ message: 'Internal server error' });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Controller function for user authentication
|
||||
exports.authenticateUser = async (req, res) => {
|
||||
try {
|
||||
const { email, password } = req.body
|
||||
|
||||
const user = await User.findOne({ email })
|
||||
|
||||
if (!user) {
|
||||
return res.status(401).json({ message: "Invalid credentials" })
|
||||
}
|
||||
|
||||
const passwordMatch = await bcrypt.compare(password, user.password)
|
||||
|
||||
if (!passwordMatch) {
|
||||
return res.status(401).json({ message: "Invalid credentials" })
|
||||
}
|
||||
|
||||
// Generate JWT token using the function from auth.js
|
||||
const token = auth.generateToken(user._id, user.email)
|
||||
|
||||
// Return user details and token
|
||||
res.status(200).json({
|
||||
userId: user._id,
|
||||
email: user.email,
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
isAdmin: user.isAdmin,
|
||||
token: token,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
res.status(500).json({ message: "Internal server error" })
|
||||
}
|
||||
}
|
||||
|
||||
// Controller function for updating user data (including email, firstName, lastName, and password)
|
||||
exports.updateUserData = async (req, res) => {
|
||||
try {
|
||||
const { userId, newEmail, newFirstName, newLastName, newPassword } = req.body;
|
||||
|
||||
// Add authentication logic here using the authorization token
|
||||
// For example:
|
||||
// const userIdFromToken = req.user.userId;
|
||||
// if (userIdFromToken !== userId) {
|
||||
// return res.status(403).json({ message: 'Permission denied. You can only update your own data.' });
|
||||
// }
|
||||
|
||||
// Your logic to update user data based on userId
|
||||
// For example:
|
||||
|
||||
const user = await User.findById(userId);
|
||||
|
||||
if (!user) {
|
||||
return res.status(404).json({ message: 'User not found' });
|
||||
}
|
||||
|
||||
// Update email if provided
|
||||
if (newEmail) {
|
||||
user.email = newEmail;
|
||||
}
|
||||
|
||||
// Update firstName if provided
|
||||
if (newFirstName) {
|
||||
user.firstName = newFirstName;
|
||||
}
|
||||
|
||||
// Update lastName if provided
|
||||
if (newLastName) {
|
||||
user.lastName = newLastName;
|
||||
}
|
||||
|
||||
// Update password if provided
|
||||
if (newPassword) {
|
||||
const hashedPassword = await bcrypt.hash(newPassword, 10);
|
||||
user.password = hashedPassword;
|
||||
}
|
||||
|
||||
// Save the updated user data
|
||||
await user.save();
|
||||
|
||||
// Fetch the updated user details
|
||||
const updatedUser = await User.findById(userId);
|
||||
|
||||
// Return the updated user details in the response
|
||||
res.status(200).json({ message: 'User data updated successfully', user: updatedUser });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({ message: 'Internal server error' });
|
||||
}
|
||||
};
|
@ -0,0 +1,37 @@
|
||||
// Dependencies
|
||||
const express = require("express")
|
||||
const mongoose = require("mongoose")
|
||||
const cors = require("cors")
|
||||
require("dotenv").config()
|
||||
const userRoute = require("./routes/user")
|
||||
|
||||
// Server start
|
||||
const app = express()
|
||||
|
||||
// Middlewares
|
||||
app.use(express.json())
|
||||
app.use(express.urlencoded({ extended: true }))
|
||||
|
||||
app.use(cors())
|
||||
|
||||
//Database
|
||||
mongoose
|
||||
.connect(process.env.MONGO_URL, {
|
||||
useNewUrlParser: true,
|
||||
useUnifiedTopology: true,
|
||||
dbName: "CSP2",
|
||||
})
|
||||
.then(() => {
|
||||
console.log("Connected to Database..")
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
// Routes
|
||||
app.use("/user", userRoute)
|
||||
|
||||
// Server up
|
||||
app.listen(process.env.PORT || 3000, () => {
|
||||
console.log(`Server is running on port ${process.env.PORT}..`)
|
||||
})
|
@ -0,0 +1,13 @@
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
const productSchema = new mongoose.Schema({
|
||||
name: { type: String, required: true },
|
||||
description: { type: String, required: true },
|
||||
price: { type: Number, required: true },
|
||||
isActive: { type: Boolean, default: true },
|
||||
createdOn: { type: Date, default: Date.now },
|
||||
});
|
||||
|
||||
const Product = mongoose.model('Product', productSchema);
|
||||
|
||||
module.exports = Product;
|
@ -0,0 +1,30 @@
|
||||
const mongoose = require("mongoose")
|
||||
|
||||
const productSchema = new mongoose.Schema({
|
||||
productId: {
|
||||
type: mongoose.Schema.Types.ObjectId,
|
||||
ref: "Product",
|
||||
required: true,
|
||||
},
|
||||
productName: { type: String, required: true },
|
||||
quantity: { type: Number, required: true },
|
||||
})
|
||||
|
||||
const userSchema = new mongoose.Schema({
|
||||
email: { type: String, required: true, unique: true },
|
||||
firstName: { type: String },
|
||||
lastName: { type: String },
|
||||
password: { type: String, required: true },
|
||||
isAdmin: { type: Boolean, default: false },
|
||||
orderedProducts: [
|
||||
{
|
||||
products: [productSchema],
|
||||
totalAmount: { type: Number, required: true },
|
||||
purchaseOn: { type: Date, default: Date.now },
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
const User = mongoose.model("User", userSchema)
|
||||
|
||||
module.exports = User
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "capstone-2",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "nodemon index.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"bcrypt": "^5.1.1",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.3.1",
|
||||
"express": "^4.18.2",
|
||||
"faker": "^5.5.3",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"mongoose": "^8.0.0",
|
||||
"nodemon": "^3.0.1"
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const productController = require('../controllers/product');
|
||||
const auth = require('./auth'); // Assuming you have an auth.js file with authentication middleware
|
||||
|
||||
// Middleware for authorization token
|
||||
const authenticateToken = auth.authenticateToken;
|
||||
|
||||
// Create a product route (accessible only by isAdmin)
|
||||
router.post('/create', authenticateToken, productController.createProduct);
|
||||
|
||||
// Retrieve all products route (accessible to both admin and normal user)
|
||||
router.get('/all', productController.getAllProducts);
|
||||
|
||||
// Retrieve all active products route (accessible to both admin and normal user)
|
||||
router.get('/active', productController.getActiveProducts);
|
||||
|
||||
module.exports = router;
|
@ -0,0 +1,17 @@
|
||||
const express = require("express")
|
||||
const router = express.Router()
|
||||
const userController = require("../controllers/user")
|
||||
const auth = require("../auth");
|
||||
|
||||
const { authenticateToken } = auth;
|
||||
|
||||
// User registration route
|
||||
router.post("/register", userController.registerUser)
|
||||
|
||||
// User authentication route
|
||||
router.post("/login", userController.authenticateUser)
|
||||
|
||||
// Update user data route
|
||||
router.put("/update", authenticateToken, userController.updateUserData)
|
||||
|
||||
module.exports = router
|
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script src="index.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,316 @@
|
||||
console.log("Hello B322!");
|
||||
|
||||
// [SECTION] if, else if and else Statement
|
||||
|
||||
let numG = -1;
|
||||
|
||||
// if statement
|
||||
// executes a statement if a specified condition is true
|
||||
if(numG < 0) {
|
||||
console.log('Hello');
|
||||
}
|
||||
|
||||
/*
|
||||
Syntax
|
||||
|
||||
if(condition){
|
||||
statement
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// The result of the expression added in the if's condition must result to true, else, the statement inside if() will not run.
|
||||
|
||||
// You can also check the condition. The expression results to a boolean true because of the use of the less than operator.
|
||||
|
||||
console.log(numG < 0);
|
||||
// results to true and so, the if statement was run.
|
||||
|
||||
numG = 0
|
||||
|
||||
if(numG < 0){
|
||||
console.log('Hello again if numA is 0!')
|
||||
};
|
||||
|
||||
// It will not run because the expression now results to false:
|
||||
console.log(numG < 0);
|
||||
|
||||
// Another sample
|
||||
|
||||
let city = "New York"
|
||||
|
||||
if(city === "New York"){
|
||||
console.log("Welcome to New York City!");
|
||||
}
|
||||
|
||||
|
||||
// else if Clause
|
||||
/*
|
||||
-Executes a statement if previous conditions are false and if the specified condition is true
|
||||
- The "else if" clause is optional and can be added to capture additional conditions to change the flow of a program.
|
||||
|
||||
*/
|
||||
|
||||
let numH = 1;
|
||||
|
||||
if(numG < 0) {
|
||||
console.log('Hello');
|
||||
} else if (numH > 0) {
|
||||
console.log('Hello from the other side');
|
||||
}
|
||||
|
||||
// We were able to run the else if() statement after we evaluated that the if condition was failed.
|
||||
|
||||
// If the if() condition was passed and run, we will no longer evaluate to else if() and end the process there.
|
||||
|
||||
let numA = -1
|
||||
|
||||
if(numA > 0) {
|
||||
console.log('Hello');
|
||||
} else if (numH > 0) {
|
||||
console.log('World');
|
||||
}
|
||||
|
||||
//else if() statement was no longer run because the if statement was able to run, the evaluation of the whole statement stops there.
|
||||
|
||||
// Let's update the city variable and look at another example:
|
||||
city = "Tokyo"
|
||||
|
||||
if(city === "New York"){
|
||||
console.log("Welcome to New York City!")
|
||||
} else if(city === "Tokyo"){
|
||||
console.log("Welcome to Tokyo, Japan!")
|
||||
};
|
||||
|
||||
// Since we failed the condition for the first if(), we went to the else if() and checked and instead passed that condition.
|
||||
|
||||
// let num = 10;
|
||||
|
||||
// if (num > 0) {
|
||||
// if (num < 5){
|
||||
// console.log("Number is between 0 and 5");
|
||||
// }else {
|
||||
// console.log("Number is greater than or equal to 5");
|
||||
// }
|
||||
// }else {
|
||||
// console.log("Number is less than or equal to 0");
|
||||
// }
|
||||
|
||||
|
||||
// if (num > 0 && num < 5) {
|
||||
// console.log("Number is between 0 and 5");
|
||||
// }else if (num >= 5) {
|
||||
// console.log("Number is greater than or equal to 5");
|
||||
// }else{
|
||||
// console.log("Number is less than or equal to 0");
|
||||
// }
|
||||
|
||||
if(numA > 0) {
|
||||
console.log('Hello');
|
||||
} else if (numH === 0) {
|
||||
console.log('World');
|
||||
} else {
|
||||
console.log('Again');
|
||||
}
|
||||
|
||||
/*
|
||||
Since both the preceding if and else if conditions failed, the else statement was run instead.
|
||||
|
||||
Else statements should only be added if there is a preceding if condition.
|
||||
|
||||
*/
|
||||
|
||||
// else {
|
||||
// console.log("Will not run without an if");
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// else if (numH === 0) {
|
||||
// console.log('World');
|
||||
// } else {
|
||||
// console.log('Again');
|
||||
// }
|
||||
|
||||
// if, else if and else statements with functions
|
||||
/*
|
||||
- Most of the times we would like to use if, else if, and else statements with functions to control the flow of our application
|
||||
- By including them inside functions, we can decide when certain conditions will be checked instead of executing statements when the JavaScript loads.
|
||||
- The "return" statement can be utilized with condtional statements in combination with functions to change values to be used for other features of our application.
|
||||
|
||||
*/
|
||||
|
||||
let message = 'No message.';
|
||||
console.log(message);
|
||||
|
||||
function determineTyphoonIntensity(windSpeed) {
|
||||
|
||||
if (windSpeed < 30) {
|
||||
return 'Not a typhoon yet.';
|
||||
}
|
||||
else if (windSpeed <= 61) {
|
||||
return 'Tropical depression detected.';
|
||||
}
|
||||
else if (windSpeed >= 62 && windSpeed <= 88) {
|
||||
return 'Tropical storm detected.';
|
||||
}
|
||||
else if (windSpeed >= 89 || windSpeed <= 117) {
|
||||
return 'Severe tropical storm detected.';
|
||||
}
|
||||
else {
|
||||
return 'Typhoon detected.';
|
||||
}
|
||||
}
|
||||
|
||||
message = determineTyphoonIntensity(110);
|
||||
console.log(message);
|
||||
|
||||
/*
|
||||
- We can further control the flow of our program based on conditions and changing variables and results
|
||||
- The initial value of "message" was "No message."
|
||||
- Due to the conditional statements created in the function, we were able to reassign it's value and use it's new value to print a different output.
|
||||
|
||||
- console.warn() is a good way to print warnings in our console that cold help us developers act on certain output within our code
|
||||
*/
|
||||
|
||||
if (message == 'Tropical storm detected.') {
|
||||
console.warn(message);
|
||||
}
|
||||
|
||||
// [SECTION] Truthy and Falsy
|
||||
|
||||
// -In Javascript a "truthy" value is a value that is considered true when ecnountered in a Boolean context
|
||||
// - Values are considered true unless defined otherwise
|
||||
// - Falsy values/exceptions for truthy:
|
||||
/*
|
||||
1. false
|
||||
2. 0
|
||||
3. -0
|
||||
4. ""
|
||||
5. null
|
||||
6. undefined
|
||||
7. NaN
|
||||
*/
|
||||
|
||||
// Truthy Examples
|
||||
// - If the result of an expression in a condition results to a truthy value, the condition retunrs true and the corresponding statements are executed
|
||||
// - Expressions are any unit of code that can bve evaluated to a value
|
||||
|
||||
if (true) {
|
||||
console.log('Truthy');
|
||||
}
|
||||
|
||||
if(1) {
|
||||
console.log('Truthy');
|
||||
}
|
||||
|
||||
if ([]) {
|
||||
console.log('Truthy');
|
||||
}
|
||||
|
||||
// Falsy examples
|
||||
|
||||
if (false) {
|
||||
console.log('Falsy');
|
||||
}
|
||||
|
||||
if (0) {
|
||||
console.log('Falsy');
|
||||
}
|
||||
|
||||
if (undefined) {
|
||||
console.log('Falsy');
|
||||
}
|
||||
|
||||
// [SECTION] Conditional (Ternary) Operator
|
||||
/*
|
||||
- The Conditional (Ternary) Operator takes in three operands:
|
||||
- 1. condition
|
||||
2. expression to execute if the condition is truthy
|
||||
3. expression to execute if the condition is falsy
|
||||
- it can be used as an alternative to an "if else" statement
|
||||
-Ternary operators have an implicit "return" statement meaning that without the return keyword, the resulting expressions can be stored in a variable.
|
||||
|
||||
- It is commonly used for single statement execution.
|
||||
*/
|
||||
|
||||
|
||||
// Single statement execution
|
||||
let ternaryResult = (1 < 18) ? true : false;
|
||||
console.log("Result of Ternary Operator " + ternaryResult);
|
||||
|
||||
// Multiple statement execution
|
||||
/*Both functions perform two seperate tasks which changes the value of the "name" variable and returns the result storing it in the "legalAge"
|
||||
*/
|
||||
|
||||
let name;
|
||||
|
||||
function isOflegalAge() {
|
||||
name = 'John';
|
||||
return 'You are of the legal age limit';
|
||||
}
|
||||
|
||||
function isUnderAge() {
|
||||
name = 'Jane';
|
||||
return 'You are under the age limit';
|
||||
}
|
||||
|
||||
let age = parseInt(prompt("What is your age?"));
|
||||
console.log(age);
|
||||
let legalAge = (age > 18) ? isOflegalAge() : isUnderAge();
|
||||
console.log("Result of Ternary Operator in functions: " + legalAge + ', ' + name);
|
||||
|
||||
|
||||
// [SECTION] Switch Statement
|
||||
|
||||
let day = prompt("What day of the week is it today?").toLowerCase();
|
||||
console.log(day);
|
||||
|
||||
switch (day) {
|
||||
case 'monday':
|
||||
console.log("The color of the day is red");
|
||||
break;
|
||||
case 'tuesday':
|
||||
console.log("The color of the day is orange");
|
||||
break;
|
||||
case 'wednesday':
|
||||
console.log("The color of the day is yellow");
|
||||
break;
|
||||
case 'thursday':
|
||||
console.log("The color of the day is green");
|
||||
break;
|
||||
case 'friday':
|
||||
console.log("The color of the day is blue");
|
||||
break;
|
||||
case 'saturday':
|
||||
console.log("The color of the day is indigo");
|
||||
break;
|
||||
case 'sunday':
|
||||
console.log("The color of the day is violet");
|
||||
break;
|
||||
default:
|
||||
console.log("Please input a valid day");
|
||||
break;
|
||||
}
|
||||
|
||||
// [SECTION] Try-Catch-Finally Statement
|
||||
|
||||
function showIntensityAlert(windSpeed) {
|
||||
try {
|
||||
|
||||
alerat(determineTyphoonIntensity(windSpeed));
|
||||
|
||||
} catch (error) {
|
||||
|
||||
console.log(typeof error);
|
||||
console.warn(error.message);
|
||||
|
||||
} finally {
|
||||
|
||||
alert('Intensity updates will show new alert.');
|
||||
}
|
||||
}
|
||||
|
||||
showIntensityAlert(56);
|
||||
|
||||
|
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>JavaScript Objects</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="./index.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,144 @@
|
||||
console.log("Hello World");
|
||||
|
||||
// console.log("Hello World");
|
||||
|
||||
//Strictly Follow the property names and spelling given in the google slide instructions.
|
||||
//Note: Do not change any variable and function names.
|
||||
//All variables and functions to be checked are listed in the exports.
|
||||
|
||||
// Create an object called trainer using object literals
|
||||
|
||||
// Initialize/add the given object properties and methods
|
||||
|
||||
// Properties
|
||||
|
||||
// Methods
|
||||
|
||||
// Check if all properties and methods were properly added
|
||||
|
||||
|
||||
// Access object properties using dot notation
|
||||
|
||||
// Access object properties using square bracket notation
|
||||
|
||||
// Access the trainer "talk" method
|
||||
|
||||
|
||||
// Create a constructor function called Pokemon for creating a pokemon
|
||||
|
||||
|
||||
// Create/instantiate a new pokemon
|
||||
|
||||
|
||||
// Create/instantiate a new pokemon
|
||||
|
||||
|
||||
// Create/instantiate a new pokemon
|
||||
|
||||
|
||||
// Invoke the tackle method and target a different object
|
||||
|
||||
|
||||
// Invoke the tackle method and target a different object
|
||||
|
||||
//=============================================================================
|
||||
|
||||
let trainer = {
|
||||
name: "Ash Ketchup",
|
||||
age: 24,
|
||||
pokemon: ["Pikachu", "Squirtle", "Charmander", "Bulbasaur"],
|
||||
friends: {
|
||||
hoenCity:["May", "Max"],
|
||||
kantoCity:["Brock", "Misty"],
|
||||
zuittCity:["Josua", "Chris", "JP", "Ron"]
|
||||
},
|
||||
talk: function(){
|
||||
console.log("Pikachu! I choose you!");
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Trainer's name: " + trainer.name)
|
||||
console.log("Age: " + trainer.age);
|
||||
trainer.talk();
|
||||
console.log(trainer.name + " summons " + trainer.pokemon[0] + "!");
|
||||
|
||||
let myPokemon = {
|
||||
name: "Pikachu",
|
||||
level: 3,
|
||||
health: 100,
|
||||
attack: 50,
|
||||
tackle: function(){
|
||||
console.log( "This Pokemon tackled targetPokemon");
|
||||
console.log( "targetPokemon's health is now reduced to _targetPokemonhealth_");
|
||||
},
|
||||
faint : function() {
|
||||
console.log("Pokemon fainted");
|
||||
}
|
||||
}
|
||||
|
||||
console.log(myPokemon);
|
||||
|
||||
function Pokemon(name, level, attack) {
|
||||
|
||||
// Properties
|
||||
this.name = name;
|
||||
this.level = level;
|
||||
this.health = 2 * level;
|
||||
this.attack = level;
|
||||
|
||||
//Methods
|
||||
this.tackle = function(target) {
|
||||
console.log(this.name + ' tackled ' + target.name);
|
||||
console.log(target.name + " health is now reduced to " + target.health);
|
||||
};
|
||||
this.faint = function(){
|
||||
console.log(this.name + ' fainted. ');
|
||||
}
|
||||
}
|
||||
|
||||
let pikachu = new Pokemon("Pikachu", 16);
|
||||
let rattata = new Pokemon('Rattata', 8);
|
||||
let raichu = new Pokemon('Raichu', 50, 50);
|
||||
|
||||
pikachu.tackle(raichu);
|
||||
// pickachu.attack(raichu);
|
||||
raichu.faint(pikachu);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Do not modify
|
||||
//For exporting to test.js
|
||||
//Note: Do not change any variable and function names. All variables and functions to be checked are listed in the exports.
|
||||
try{
|
||||
module.exports = {
|
||||
|
||||
trainer: typeof trainer !== 'undefined' ? trainer : null,
|
||||
Pokemon: typeof Pokemon !== 'undefined' ? Pokemon : null
|
||||
|
||||
}
|
||||
} catch(err){
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="index.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,121 @@
|
||||
console.log("Hello World");
|
||||
|
||||
let users = ["Dwayne Johnson","Steve Austin","Kurt Angle","Dave Bautista"];
|
||||
|
||||
console.log("Original Array:")
|
||||
console.log(users);
|
||||
|
||||
/*
|
||||
Important note: Don't pass the array as an argument to the function.
|
||||
The functions must be able to manipulate the current users array.
|
||||
*/
|
||||
|
||||
/*
|
||||
1. Create a function called addItem which is able to receive a single argument and add the input at the end of the users array.
|
||||
-function should be able to receive a single argument.
|
||||
-add the input data at the end of the array.
|
||||
-The function should not be able to return data.
|
||||
-invoke and add an argument to be passed in the function.
|
||||
-log the users array in the console.
|
||||
|
||||
*/
|
||||
function addItem() {
|
||||
users[4] = "John Cena";
|
||||
console.log(users);
|
||||
}
|
||||
addItem();
|
||||
|
||||
/*
|
||||
2. Create function called getItemByIndex which is able to receive an index number as a single argument return the item accessed by its index.
|
||||
-function should be able to receive a single argument.
|
||||
-return the item accessed by the index.
|
||||
-Create a global variable called outside of the function called itemFound and store the value returned by the function in it.
|
||||
-log the itemFound variable in the console.
|
||||
|
||||
*/
|
||||
function getItemByIndex() {
|
||||
return console.log(users[2]), console.log(users[4]);
|
||||
}
|
||||
let itemFound = getItemByIndex;
|
||||
itemFound();
|
||||
|
||||
/*
|
||||
3. Create function called deleteItem which is able to delete the last item in the array and return the deleted item.
|
||||
-Create a function scoped variable to store the last item in the users array.
|
||||
-Shorten the length of the array by at least 1 to delete the last item.
|
||||
-return the last item in the array which was stored in the variable.
|
||||
|
||||
*/
|
||||
function deleteItem() {
|
||||
let users = ["Dwayne Johnson","Steve Austin","Kurt Angle","Dave Bautista"];
|
||||
users.length--;
|
||||
console.log(users);
|
||||
}
|
||||
deleteItem();
|
||||
|
||||
|
||||
/*
|
||||
4. Create function called updateItemByIndex which is able to update a specific item in the array by its index.
|
||||
-Function should be able to receive 2 arguments, the update and the index number.
|
||||
-First, access and locate the item by its index then re-assign the item with the update.
|
||||
-This function should not have a return.
|
||||
-Invoke the function and add the update and index number as arguments.
|
||||
-log the users array in the console.
|
||||
|
||||
*/
|
||||
let newArr = users;
|
||||
function updateItemByIndex() {
|
||||
newArr[users.length-5] = "Ron Reciproco";
|
||||
console.log(newArr);
|
||||
}
|
||||
updateItemByIndex();
|
||||
|
||||
|
||||
|
||||
/*
|
||||
5. Create function called deleteAll which is able to delete all items in the array.
|
||||
-You can modify/set the length of the array.
|
||||
-The function should not return anything.
|
||||
|
||||
*/
|
||||
function deleteAll() {
|
||||
users.length = users.length-5;
|
||||
console.log(users);
|
||||
}
|
||||
deleteAll();
|
||||
|
||||
|
||||
/*
|
||||
6. Create a function called isEmpty which is able to check if the array is empty.
|
||||
-Add an if statement to check if the length of the users array is greater than 0.
|
||||
-If it is, return false.
|
||||
-Else, return true.
|
||||
-Create a global variable called outside of the function called isUsersEmpty and store the returned value from the function.
|
||||
-log the isUsersEmpty variable in the console.
|
||||
|
||||
*/
|
||||
function isEmpty() {
|
||||
if (users.length >= 1 ) {
|
||||
console.log(true);
|
||||
} else {
|
||||
console.log(false);
|
||||
}
|
||||
console.log(users.length);
|
||||
}
|
||||
isEmpty();
|
||||
//Note: Do not change any variable and function names. All variables and functions to be checked are listed in the exports.
|
||||
try{
|
||||
module.exports = {
|
||||
|
||||
users: typeof users !== 'undefined' ? users : null,
|
||||
addItem: typeof addItem !== 'undefined' ? addItem : null,
|
||||
getItemByIndex: typeof getItemByIndex !== 'undefined' ? getItemByIndex : null,
|
||||
deleteItem: typeof deleteItem !== 'undefined' ? deleteItem : null,
|
||||
updateItemByIndex: typeof updateItemByIndex !== 'undefined' ? updateItemByIndex : null,
|
||||
deleteAll: typeof deleteAll !== 'undefined' ? deleteAll : null,
|
||||
isEmpty: typeof isEmpty !== 'undefined' ? isEmpty : null,
|
||||
|
||||
}
|
||||
} catch(err){
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="index.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,115 @@
|
||||
console.log("Array Traversals")
|
||||
|
||||
let studentNumberA = '2020-1923'
|
||||
let studentNumberB = '2020-1924'
|
||||
let studentNumberC = '2020-1925'
|
||||
let studentNumberE = '2020-1926'
|
||||
let studentNumberD = '2020-1927'
|
||||
|
||||
// Now with an array, we can simply write the code above like this:
|
||||
|
||||
let studentNumbers = ['2020-1923','2020-1924','2020-1925','2020-1926','2020-1927'];
|
||||
|
||||
// [SECTION] Arrays
|
||||
|
||||
// - Arrays are used to store multiple related values in a single variable
|
||||
|
||||
// - They are declared using square brackets for ([]) also known as Array Literals
|
||||
|
||||
// - Commonly used to store numerous amounts of data to manipulate in order to perform a number of tasks.
|
||||
|
||||
// Majority of methods are used to manipulate information stored within the same object
|
||||
|
||||
// - Syntax
|
||||
// let/const arrayName = [elementA, elementB, elementC ]
|
||||
|
||||
let grades = [98.5, 94.3, 89.2, 90.1]
|
||||
let computerBrands = ['Acer', 'Asus', 'Lenovo', 'Neo', 'RedFox', 'Gateway', 'Toshiba', 'Fujitsu'];
|
||||
|
||||
console.log(grades);
|
||||
console.log(computerBrands);
|
||||
// console.log(mixedArr);
|
||||
|
||||
// Alternative way to write arrays
|
||||
|
||||
let myTasks = [
|
||||
'drink html',
|
||||
'eat javascript',
|
||||
'inhale css',
|
||||
'bake sass'
|
||||
];
|
||||
|
||||
// Creating an array with values from variables:
|
||||
let city1 = "Tokyo";
|
||||
let city2 = "Manila";
|
||||
let city3 = "Jakarta";
|
||||
|
||||
let cities = [city1,
|
||||
city2,
|
||||
city3
|
||||
];
|
||||
|
||||
console.log(myTasks);
|
||||
console.log(cities);
|
||||
|
||||
// [SECTION] length property
|
||||
|
||||
// The .length property allows us to get and set the total number of items in an array.
|
||||
|
||||
console.log(myTasks.length);
|
||||
console.log(cities.length);
|
||||
|
||||
let blankArr = [];
|
||||
console.log(blankArr.length);
|
||||
|
||||
let fullname = 'Jamie Noble';
|
||||
console.log(fullname.length);
|
||||
|
||||
// length property on strings show the number of characters in a string.
|
||||
// Spaces are counted as characters in strings.
|
||||
|
||||
// length property can also set the total number of items in an array. meaning we can actually delete the last item in the arraw or shorten the array by simply updating the length property of an array.
|
||||
|
||||
myTasks.length = myTasks.length-1;
|
||||
console.log(myTasks.length);
|
||||
console.log(myTasks);
|
||||
|
||||
// To delete a specific item in an array we can employ array methods ( which will be shown in the next session ) or an algoritm (set of code to process tasks. )
|
||||
|
||||
// Another example using decrementation
|
||||
|
||||
cities.length--;
|
||||
console.log(cities);
|
||||
|
||||
fullname.length = fullname.length-1;
|
||||
console.log(fullname.length);
|
||||
fullname.length--;
|
||||
console.log(fullname);
|
||||
|
||||
let theBeatles = ["John", "Paul", "Ringo", "George"];
|
||||
theBeatles.length++;
|
||||
console.log(theBeatles);
|
||||
|
||||
// theBeatles.length = theBeatles.length+2;
|
||||
// console.log(theBeatles);
|
||||
|
||||
|
||||
// [SECTION] Reading from arrays [ Index Numbers ]
|
||||
// Syntax
|
||||
// arrayName[index];
|
||||
|
||||
console.log(grades[0]);
|
||||
console.log(computerBrands[3]);
|
||||
|
||||
|
||||
// Accessing an array element that does not exist will return 'undefined"
|
||||
console.log(grades[20]);
|
||||
|
||||
let lakersLegends = ["Kobe", "Shaq", "LeBron", "Magic", "Kareem"];
|
||||
console.log(lakersLegends[1]);
|
||||
// Access the second item in the array
|
||||
console.log(lakersLegends[3]);
|
||||
// Access the fourth item in the array
|
||||
|
||||
let currentLaker = lakersLegends[2];
|
||||
console.log(currentLaker);
|
@ -0,0 +1,132 @@
|
||||
<mxfile host="Electron" modified="2023-10-18T12:34:15.329Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/22.0.2 Chrome/114.0.5735.289 Electron/25.8.4 Safari/537.36" etag="56GYDva5FrMb8ERo_q9q" version="22.0.2" type="device">
|
||||
<diagram id="R2lEEEUBdFMjLlhIrx00" name="Page-1">
|
||||
<mxGraphModel dx="1195" dy="703" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0" extFonts="Permanent Marker^https://fonts.googleapis.com/css?family=Permanent+Marker">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-45" value="Order Products" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;align=center;fontSize=14;" vertex="1" parent="1">
|
||||
<mxGeometry x="520" y="510" width="160" height="176" as="geometry">
|
||||
<mxRectangle x="120" y="190" width="60" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-47" value="Order ID (string)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-45">
|
||||
<mxGeometry y="26" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-48" value="Product ID (string)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-45">
|
||||
<mxGeometry y="56" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-49" value="Quantity (number)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-45">
|
||||
<mxGeometry y="86" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-50" value="Price (number)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-45">
|
||||
<mxGeometry y="116" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-52" value="Sub Total (number)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-45">
|
||||
<mxGeometry y="146" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-54" value="Users" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;align=center;fontSize=14;" vertex="1" parent="1">
|
||||
<mxGeometry x="120" y="105" width="160" height="236" as="geometry">
|
||||
<mxRectangle x="120" y="190" width="60" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-55" value="<span style="font-weight: normal;">id (accountID)</span>" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;fontStyle=1" vertex="1" parent="1rynRFJusVIlwAZYDo_v-54">
|
||||
<mxGeometry y="26" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-56" value="First Name (string)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-54">
|
||||
<mxGeometry y="56" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-57" value="Last Name (string)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-54">
|
||||
<mxGeometry y="86" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-58" value="Email (string)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-54">
|
||||
<mxGeometry y="116" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-59" value="Password (string)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-54">
|
||||
<mxGeometry y="146" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-60" value="is Admin (boolean)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-54">
|
||||
<mxGeometry y="176" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-61" value="Mobile Number (string)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-54">
|
||||
<mxGeometry y="206" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-64" value="Products" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;align=center;fontSize=14;" vertex="1" parent="1">
|
||||
<mxGeometry x="510" y="105" width="160" height="206" as="geometry">
|
||||
<mxRectangle x="120" y="190" width="60" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-65" value="Name (string)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-64">
|
||||
<mxGeometry y="26" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-66" value="Description (string)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-64">
|
||||
<mxGeometry y="56" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-67" value="Price (number)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-64">
|
||||
<mxGeometry y="86" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-68" value="Stocks (number)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-64">
|
||||
<mxGeometry y="116" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-69" value="Is Active? (boolean)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-64">
|
||||
<mxGeometry y="146" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-70" value="SKU (string)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-64">
|
||||
<mxGeometry y="176" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-72" value="Orders" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;align=center;fontSize=14;" vertex="1" parent="1">
|
||||
<mxGeometry x="120" y="510" width="160" height="146" as="geometry">
|
||||
<mxRectangle x="120" y="190" width="60" height="30" as="alternateBounds" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-73" value="User ID (string)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-72">
|
||||
<mxGeometry y="26" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-74" value="Transaction Date (string)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-72">
|
||||
<mxGeometry y="56" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-75" value="Status (string)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-72">
|
||||
<mxGeometry y="86" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-76" value="Total (number)" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="1rynRFJusVIlwAZYDo_v-72">
|
||||
<mxGeometry y="116" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-86" value="" style="edgeStyle=entityRelationEdgeStyle;fontSize=12;html=1;endArrow=ERoneToMany;rounded=0;exitX=1;exitY=0.3;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitPerimeter=0;" edge="1" parent="1" source="1rynRFJusVIlwAZYDo_v-60">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<mxPoint x="280" y="270" as="sourcePoint" />
|
||||
<mxPoint x="510" y="270" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-87" value="" style="edgeStyle=entityRelationEdgeStyle;fontSize=12;html=1;endArrow=ERmany;startArrow=ERmany;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" target="1rynRFJusVIlwAZYDo_v-70">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<mxPoint x="690" y="520" as="sourcePoint" />
|
||||
<mxPoint x="767.6000000000001" y="287.84000000000003" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-90" value="" style="edgeStyle=entityRelationEdgeStyle;fontSize=12;html=1;endArrow=ERoneToMany;startArrow=ERmandOne;rounded=0;entryX=-0.005;entryY=0.839;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" target="1rynRFJusVIlwAZYDo_v-48">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<mxPoint x="280" y="591" as="sourcePoint" />
|
||||
<mxPoint x="440" y="600" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-93" value="One to many" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="340" y="240" width="90" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-94" value="Many to Many" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="615" y="400" width="100" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-95" value="Many Optional to mandatory" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="305" y="550" width="170" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-110" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=0.458;entryY=1.144;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.469;exitY=-0.021;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="1rynRFJusVIlwAZYDo_v-72" target="1rynRFJusVIlwAZYDo_v-61">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="390" y="480" as="sourcePoint" />
|
||||
<mxPoint x="440" y="430" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="1rynRFJusVIlwAZYDo_v-111" value="1 Mandatory to Many Optional" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="205" y="430" width="180" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
@ -0,0 +1,17 @@
|
||||
{
|
||||
"_id": "6062a8eb835de22e84600edd",
|
||||
"userId": "507f1f77bcf86cd799439011",
|
||||
"courseId": "601ccbe89bcd482ee8fa2c99",
|
||||
"isPaid": true,
|
||||
"paymentMethod": "Paypal",
|
||||
"datetimeCreated": "2020-03-10T15:00:00.00Z"
|
||||
}
|
||||
|
||||
{
|
||||
"_id": "6032a8eb856de22e24600ebb",
|
||||
"userId": "507f1f77bcf86cd799439012",
|
||||
"courseId": "601ccbe89bcd888ee8fa2cea",
|
||||
"isPaid": true,
|
||||
"paymentMethod": "American Express - Credit",
|
||||
"datetimeCreated": "2020-03-12T15:00:00.00Z"
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
{
|
||||
"_id": "601ccbe89bcd482ee8fa2c99",
|
||||
"name": "HTML",
|
||||
"description": "Learn the basics and how to code.",
|
||||
"price": 1000,
|
||||
"isActive": true,
|
||||
"slots": "20",
|
||||
"enrollees": ["507f1f77bcf86cd799439011"],
|
||||
"datetimeCreated": "2020-03-10T15:00:00.00Z"
|
||||
}
|
||||
|
||||
{
|
||||
"_id": "507f191e810c19729de860ea",
|
||||
"name": "CSS",
|
||||
"description": "Let's make our application look cool!",
|
||||
"price": 2000,
|
||||
"isActive": false,
|
||||
"slots": "20",
|
||||
"enrollees": ["507f1f77bcf86cd799439011"],
|
||||
"datetimeCreated": "2021-08-15T15:00:00.00Z"
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
{
|
||||
"_id": "601ccbe89bcd482ee8fa2c99",
|
||||
"name": "HTML",
|
||||
"description": "Learn the basics and how to code.",
|
||||
"price": 1000,
|
||||
"isActive": true,
|
||||
"slots": "20",
|
||||
"enrollees": ["507f1f77bcf86cd799439011"],
|
||||
"datetimeCreated": "2020-03-10T15:00:00.00Z"
|
||||
}
|
||||
|
||||
{
|
||||
"_id": "507f191e810c19729de860ea",
|
||||
"name": "CSS",
|
||||
"description": "Let's make our application look cool!",
|
||||
"price": 2000,
|
||||
"isActive": false,
|
||||
"slots": "20",
|
||||
"enrollees": ["507f1f77bcf86cd799439011"],
|
||||
"datetimeCreated": "2021-08-15T15:00:00.00Z"
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
{
|
||||
"_id": "507f1f77bcf86cd799439011",
|
||||
"firstName": "John",
|
||||
"lastName": "Smith",
|
||||
"email": "johnsmith@mail.com",
|
||||
"password": "johnhandsome",
|
||||
"isAdmin": false,
|
||||
"mobileNumber": "09221231234",
|
||||
"enrollments": ["601ccbe89bcd482ee8fa2c99", "507f191e810c19729de860ea"],
|
||||
"datetimeRegistered": "2020-03-15T15:00:00.00Z"
|
||||
}
|
||||
|
||||
{
|
||||
"_id": "507f1f77bcf86cd799439011",
|
||||
"firstName": "Jane",
|
||||
"lastName": "Doe",
|
||||
"email": "janedoe@zuitt.com",
|
||||
"password": "johnhandsome",
|
||||
"isAdmin": true,
|
||||
"mobileNumber": "09277365528",
|
||||
"enrollments": [],
|
||||
"datetimeRegistered": "2020-03-15T15:00:00.00Z"
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
{
|
||||
"_id": "601ccbe89bcd482ee8fa2c99",
|
||||
"name": "HTML",
|
||||
"description": "Learn the basics and how to code.",
|
||||
"price": 1000,
|
||||
"isActive": true,
|
||||
"slots": "20",
|
||||
"enrollees": ["507f1f77bcf86cd799439011"],
|
||||
"datetimeCreated": "2020-03-10T15:00:00.00Z"
|
||||
}
|
||||
|
||||
{
|
||||
"_id": "507f191e810c19729de860ea",
|
||||
"name": "CSS",
|
||||
"description": "Let's make our application look cool!",
|
||||
"price": 2000,
|
||||
"isActive": false,
|
||||
"slots": "20",
|
||||
"enrollees": ["507f1f77bcf86cd799439011"],
|
||||
"datetimeCreated": "2021-08-15T15:00:00.00Z"
|
||||
}
|
||||
|
||||
{
|
||||
"_id": "601ccc169bcd482ee8fa2c9a",
|
||||
"name": "JavaScript",
|
||||
"description": "Make websites fun and interactive!",
|
||||
"price": 4000,
|
||||
"isActive": true,
|
||||
"slots": "15",
|
||||
"enrollees": [],
|
||||
"datetimeCreated": "2022-02-01T15:00:00.00Z"
|
||||
}
|
||||
|
@ -0,0 +1 @@
|
||||
node_modules
|
@ -0,0 +1,104 @@
|
||||
const express = require("express");
|
||||
const mongoose = require("mongoose");
|
||||
|
||||
const app = express();
|
||||
const port = 3001;
|
||||
|
||||
|
||||
// Connecting to MongoDB Atlas
|
||||
mongoose.connect("mongodb+srv://ronreciproco123:admin123@cluster0.9ao1xec.mongodb.net/b322_to-do?retryWrites=true&w=majority", {
|
||||
useNewUrlParser: true,
|
||||
useUnifiedTopology: true
|
||||
});
|
||||
|
||||
let db = mongoose.connection;
|
||||
|
||||
db.on("error", console.error.bind(console, "connection error"));
|
||||
|
||||
db.once("open", () => console.log("We're connected to the cloud database"));
|
||||
|
||||
// [Section] Mongoose Schemas
|
||||
// Schema is the blueprint of our "task" documents
|
||||
const taskSchema = new mongoose.Schema({
|
||||
name: String,
|
||||
status: {
|
||||
type: String,
|
||||
default: "pending"
|
||||
}
|
||||
});
|
||||
|
||||
// [Section] Models
|
||||
const Task = mongoose.model("Task", taskSchema);
|
||||
|
||||
// Middlewares
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({extended:true}));
|
||||
|
||||
app.post("/tasks", (req, res) => {
|
||||
|
||||
Task.findOne({name: req.body.name}).then((result, error) => {
|
||||
|
||||
if(result != null && result.name == req.body.name){
|
||||
|
||||
return res.send("Duplicate task found!");
|
||||
|
||||
} else {
|
||||
|
||||
let newTask = new Task({
|
||||
name: req.body.name
|
||||
});
|
||||
|
||||
newTask.save().then((saveTask, saveErr) => {
|
||||
if(saveErr){
|
||||
return console.error(saveErr);
|
||||
} else {
|
||||
return res.status(201).send("New task created!");
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
// Activity Output
|
||||
|
||||
app.post('/signup', async (req, res) => {
|
||||
try {
|
||||
const { username, password } = req.body;
|
||||
|
||||
console.log('Received data from Postman:');
|
||||
console.log('Username:', username);
|
||||
console.log('Password:', password);
|
||||
|
||||
// Create a new user
|
||||
const newUser = new User({ username, password });
|
||||
|
||||
// Save the user to the database
|
||||
await newUser.save();
|
||||
|
||||
res.status(201).json({ message: 'User created successfully' });
|
||||
} catch (err) {
|
||||
console.error('Error:', err);
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// app.get("/tasks", (req, res) => {
|
||||
|
||||
// Task.find({}).then((result, error) => {
|
||||
// if(error){
|
||||
// return console.log(error);
|
||||
// } else {
|
||||
// return res.status(200).json({
|
||||
// data: result
|
||||
// })
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
|
||||
if(require.main === module){
|
||||
app.listen(port, () => console.log(`Server running at port ${port}`));
|
||||
}
|
||||
|
||||
module.export = app;
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "s41",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"mongoose": "^7.6.4",
|
||||
"nodemon": "^3.0.1"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue