init commit
@@ -0,0 +1,80 @@
|
|||||||
|
VERSION=2.0.0
|
||||||
|
MODE=development
|
||||||
|
NODE_ENV=development
|
||||||
|
ENV=development
|
||||||
|
PLATFORM_NAME=Test
|
||||||
|
MAIL_FROM=
|
||||||
|
MAIL_DOMAIN=
|
||||||
|
MAILGUN_KEY=
|
||||||
|
TWILIO_PHONE_NUMBER=
|
||||||
|
TWILIO_SID=
|
||||||
|
TWILIO_TOKEN=
|
||||||
|
COPYRIGHT=Copyright © 2021 MKD. All rights reserved.
|
||||||
|
POWERED_BY=Powered By <a href="MDK.com" target="__blank">MKD.ca</a>
|
||||||
|
NODE_PORT=3001
|
||||||
|
GRAPHQL_PORT=9001
|
||||||
|
EMAIL_SMTP_PROTOCOL=smtp
|
||||||
|
EMAIL_SMTP_SMTP_HOST=smtp.mailtrap.io
|
||||||
|
EMAIL_SMTP_SMTP_PORT=2525
|
||||||
|
EMAIL_SMTP_SMTP_USER=7e8f296dd6a493
|
||||||
|
EMAIL_SMTP_SMTP_PASS=ac4e30d39321bc
|
||||||
|
EMAIL_SMTP_CRLF=\r\n
|
||||||
|
EMAIL_SMTP_NEWLINE=\r\n
|
||||||
|
EMAIL_SMTP_MAILTYPE=html
|
||||||
|
EMAIL_SMTP_CHARSET=utf-8
|
||||||
|
CSRF_EXCLUDE_URIS=["v1/api.*+","member/login","member/forgot","member/reset/.*","member/register","admin/login","admin/forgot","admin/reset/.*","admin/register","sale/login","sale/forgot","sale/reset/.*","sale/register"]
|
||||||
|
ENCRYPTION_KEY=1n4uUX6d1Us3quFXKA7ZmqFIaQVC5MtgXlV9ho8F
|
||||||
|
SUBCLASS_PREFIX=Manaknight_
|
||||||
|
MIGRATION_NUMBER=9377770345344
|
||||||
|
LANGUAGE=english
|
||||||
|
BASE_URL=http://localhost:3001
|
||||||
|
SITE_TITLE=Manaknight Saas
|
||||||
|
COMPANY=MKd
|
||||||
|
IMAGE_UPLOAD=local
|
||||||
|
FILE_UPLOAD=local
|
||||||
|
UPLOAD_BYTE_SIZE_LIMIT=1000000000
|
||||||
|
SESSION_SECRET=ACbe28dfeaeb2635aac92c05660664588b
|
||||||
|
SHOPIFY_SITE=skincare.myshopify.com
|
||||||
|
SHOPIFY_API_KEY=22a
|
||||||
|
SHOPIFY_API_PASSWORD=shppa
|
||||||
|
SHOPIFY_SECRET_KEY=shpss
|
||||||
|
SHOPIFY_SCOPES=write_script_tags,read_script_tags,read_content,write_content,read_products
|
||||||
|
API_URL=http://localhost:3001
|
||||||
|
DYNAMIC_CONFIG_JWT_KEY=544e
|
||||||
|
DYNAMIC_CONFIG_PERMISSION_ENCRYPT_KEY=vOV
|
||||||
|
DYNAMIC_CONFIG_JWT_EXPIRE_AT=3600
|
||||||
|
DYNAMIC_CONFIG_JWT_REFRESH_EXPIRE_AT=7200
|
||||||
|
DYNAMIC_CONFIG_GOOGLE_CLIENT_ID=466040660536-l5pq116jdp6cs3b58a7k4t52f5lpa5se.apps.googleusercontent.com
|
||||||
|
DYNAMIC_CONFIG_GOOGLE_CLIENT_SECRET=W_bYoRhly8pf0XJ1IUsk8wC_
|
||||||
|
DYNAMIC_CONFIG_GOOGLE_REDIRECT_URI=http://localhost:3001/google
|
||||||
|
DYNAMIC_CONFIG_APPLICATION_NAME=
|
||||||
|
DYNAMIC_CONFIG_FACEBOOK_CLIENT_ID=906124643482094
|
||||||
|
DYNAMIC_CONFIG_FACEBOOK_CLIENT_SECRET=ee289adf5399aaa48c2bbfd33b83c301
|
||||||
|
DYNAMIC_CONFIG_FACEBOOK_REDIRECT_URI=http://localhost:3001/facebook
|
||||||
|
DYNAMIC_CONFIG_FACEBOOK_OATH_URI=https://www.facebook.com/v3.0/dialog/oauth
|
||||||
|
DYNAMIC_CONFIG_AWS_VERSION=latest
|
||||||
|
DYNAMIC_CONFIG_AWS_REGION=us-east-2
|
||||||
|
DYNAMIC_CONFIG_AWS_KEY=AKIAJD27VH2ITMIWT4IQ
|
||||||
|
DYNAMIC_CONFIG_AWS_SECRET=GGxKr5BKEroxwRETY0Iu3kEDvAvoxXqZGUncMKj8
|
||||||
|
DYNAMIC_CONFIG_AWS_BUCKET=com.konfor.images
|
||||||
|
DB_ADAPTER=mysql
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DSN=
|
||||||
|
DB_HOSTNAME=localhost
|
||||||
|
DB_USERNAME=root
|
||||||
|
DB_PASSWORD=
|
||||||
|
DB_DATABASE=mkd
|
||||||
|
DB_DBDRIVER=mysqli
|
||||||
|
DB_DBPREFIX=
|
||||||
|
DB_PCONNECT=false
|
||||||
|
DB_DB_DEBUG=false
|
||||||
|
DB_CACHE_ON=false
|
||||||
|
DB_CACHEDIR=
|
||||||
|
DB_CHAR_SET=utf8
|
||||||
|
DB_DBCOLLAT=utf8_general_ci
|
||||||
|
DB_SWAP_PRE=
|
||||||
|
DB_ENCRYPT=false
|
||||||
|
DB_COMPRESS=false
|
||||||
|
DB_STRICTON=false
|
||||||
|
DB_FAILOVER=
|
||||||
|
DB_SAVE_QUERIES=true
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
#testing files
|
||||||
|
!public/uploads/.gitkeep
|
||||||
|
# services/SessionService.js
|
||||||
|
test.js
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
.DS_Store
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# TypeScript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and *not* Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
# Explain project
|
||||||
|
|
||||||
|
## Files and folders you will working on for the quiz are the following
|
||||||
|
|
||||||
|
- /public/quiz-test.html
|
||||||
|
- /public/frontend_css/styles and mobile_styles.css
|
||||||
|
- /public/frontend_js/quiz-test.js
|
||||||
|
- /models/
|
||||||
|
- /controllers/admin/
|
||||||
|
- /views/admin
|
||||||
|
- /views/partials/admin/nav.eta
|
||||||
|
|
||||||
|
Admin login
|
||||||
|
|
||||||
|
localhost:3001/admin/login
|
||||||
|
|
||||||
|
email: admin@manaknight.com
|
||||||
|
|
||||||
|
password: a123456
|
||||||
|
|
||||||
|
View the quiz on localhost:3001/quiz-test.html
|
||||||
|
|
||||||
|
Video Demo https://www.loom.com/share/cb8be1cf3fad45bc8f2ecaca4704e367
|
||||||
|
|
||||||
|
### Quiz 1
|
||||||
|
|
||||||
|
Response page of question What would you like to be called?.<br>
|
||||||
|
Make the name appears centered inside of the jar gif.<br>
|
||||||
|
<br>
|
||||||
|
You can change the html or the css to do this task.<br>
|
||||||
|
|
||||||
|
### Quiz 2
|
||||||
|
|
||||||
|
Each response page should be closed after a set amount of time<br>
|
||||||
|
The setTimeout of the response page of previous quiz is not working<br>
|
||||||
|
Figure out where this is handled and make a setTimeout to close the response and move on to the next question using the time stored in variable called "closeResponseTimeoutCounter"<br>
|
||||||
|
|
||||||
|
### Quiz 3
|
||||||
|
|
||||||
|
We have multiple types of questions type 7 being "multiple select"<br>
|
||||||
|
You are required to find where it is handled<br>
|
||||||
|
Then make the button of each option call checkAllergie function that you will be implementing in the next quiz<br>
|
||||||
|
Then add an option at the end of all options that says None of the above and onclick it should call this function handleNoneOfTheAbove()<br>
|
||||||
|
|
||||||
|
### Quiz 4
|
||||||
|
|
||||||
|
implement a function that is called checkAllergie()<br>
|
||||||
|
pseudo steps of the function
|
||||||
|
|
||||||
|
- find a way to read the dataset values on the html button element that generated the click
|
||||||
|
- each button should have data-val that contains the label of the option
|
||||||
|
- check if that previous val is equal to one of these values ["Banana", "Olive", "Sunflowers"]
|
||||||
|
- if true -> terminate the quiz
|
||||||
|
- function terminateQuiz should do the following
|
||||||
|
- the termination process need to display a message to the user with a faded black background that has a message and a counter that when it reachs 0 it redirect to /
|
||||||
|
- ex: 
|
||||||
|
- message and counter should be controlled from admin portal
|
||||||
|
- create a terminate configuration table with the appropriate fields
|
||||||
|
- create a tab in admin portal to edit these fields
|
||||||
|
- create an api to get these configuration and use it here to construct the termination screen
|
||||||
|
|
||||||
|
### Quiz 5
|
||||||
|
|
||||||
|
implement 2nd step of calculation on quiz answers
|
||||||
|
|
||||||
|
- after quiz is done. a calculation step takes place. you are required to figure out how to implement the missing function.
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
"use strict";
|
||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2020*/
|
||||||
|
/**
|
||||||
|
* App
|
||||||
|
* @copyright 2020 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
require("dotenv").config();
|
||||||
|
const { getLocalPath } = require("./core/helpers");
|
||||||
|
const fs = require("fs");
|
||||||
|
const express = require("express");
|
||||||
|
const path = require("path");
|
||||||
|
const body_parser = require("body-parser");
|
||||||
|
const logger = require("morgan");
|
||||||
|
const helmet = require("helmet");
|
||||||
|
const PowerByService = require("./services/PowerByService");
|
||||||
|
const UploadService = require("./services/UploadService");
|
||||||
|
const cookieParser = require("cookie-parser");
|
||||||
|
const controllersEndpoints = require("./controllers/index");
|
||||||
|
const portalsEndpoints = require("./routes/index");
|
||||||
|
const db = require("./models");
|
||||||
|
const sessionClass = require("express-session");
|
||||||
|
const flash = require("connect-flash");
|
||||||
|
const cors = require("cors");
|
||||||
|
const sizeOf = require("image-size");
|
||||||
|
let app = express();
|
||||||
|
const expressip = require("express-ip");
|
||||||
|
|
||||||
|
if (process.NODE_ENV === "maintenance") {
|
||||||
|
app.all("*", (req, res) => {
|
||||||
|
res.status(503).json({ message: "website under maintenance" });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
app.set("iocContainer", process.env);
|
||||||
|
app.set("db", db);
|
||||||
|
app.use(expressip().getIpInfoMiddleware);
|
||||||
|
app.use(logger("dev"));
|
||||||
|
app.use(
|
||||||
|
express.json({
|
||||||
|
limit: "50mb",
|
||||||
|
verify: (req, res, buf) => {
|
||||||
|
req.rawBody = buf;
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
app.use(
|
||||||
|
express.urlencoded({
|
||||||
|
extended: false,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
app.use(cors());
|
||||||
|
app.use(flash());
|
||||||
|
let session = {
|
||||||
|
secret: process.env.SESSION_SECRET,
|
||||||
|
resave: true,
|
||||||
|
saveUninitialized: true,
|
||||||
|
name: "session",
|
||||||
|
proxy: true,
|
||||||
|
cookie: { maxAge: 60 * 60 * 1000 },
|
||||||
|
};
|
||||||
|
|
||||||
|
app.set("trust proxy", true);
|
||||||
|
if (process.env.NODE_ENV === "production") {
|
||||||
|
session.cookie.secure = true; // serve secure cookies
|
||||||
|
}
|
||||||
|
app.use(sessionClass(session));
|
||||||
|
app.set("view engine", "eta");
|
||||||
|
app.set("views", path.join(__dirname, "/views"));
|
||||||
|
app.use(cookieParser());
|
||||||
|
app.use(helmet());
|
||||||
|
|
||||||
|
app.use(PowerByService);
|
||||||
|
app.use(express.static(path.join(__dirname, "/public")));
|
||||||
|
|
||||||
|
app.get("/version", (req, res) => res.status(200).json({ version: process.env.VERSION }));
|
||||||
|
app.get("/", (req, res, next) => {
|
||||||
|
return res.send("<h1 style='text-align:left;'>Live!</h1>");
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use((err, req, res, next) => {
|
||||||
|
// set locals, only providing error in development
|
||||||
|
res.locals.message = err.message;
|
||||||
|
res.locals.error = req.app.get("env") === "development" ? err : {};
|
||||||
|
|
||||||
|
// render the error page
|
||||||
|
res.status(err.status || 500);
|
||||||
|
res.json({
|
||||||
|
message: err.message,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//local upload default
|
||||||
|
const upload = UploadService.local_upload();
|
||||||
|
app.post("/v1/upload/file", upload.single("file"), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
const url = getLocalPath(req.file.path);
|
||||||
|
let params = {
|
||||||
|
url: url,
|
||||||
|
user_id: req.session?.user || null,
|
||||||
|
caption: req.body?.caption || null,
|
||||||
|
type: +req.body?.type || null,
|
||||||
|
};
|
||||||
|
const uploadedfile = fs.readFileSync(req.file.path);
|
||||||
|
if (!req.file.mimetype.includes("video")) {
|
||||||
|
const dimensions = sizeOf(uploadedfile);
|
||||||
|
params.width = dimensions.width;
|
||||||
|
params.height = dimensions.height;
|
||||||
|
}
|
||||||
|
let createdImage = await db.image.insert(params);
|
||||||
|
return res.status(201).json({ id: createdImage, url });
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
return res.status(500).json({ error: true, message: error.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use(portalsEndpoints);
|
||||||
|
app.use(controllersEndpoints);
|
||||||
|
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
return res.status(404).send("<h1 style='text-align:left;'>Not found!</h1>");
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"lambda": {
|
||||||
|
"role": "graphql_provider-executor",
|
||||||
|
"name": "graphql_project",
|
||||||
|
"region": "us-east-2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,336 @@
|
|||||||
|
"use strict";
|
||||||
|
const axios = require("axios");
|
||||||
|
|
||||||
|
const app = require("express").Router();
|
||||||
|
const Sequelize = require("sequelize");
|
||||||
|
const logger = require("../../services/LoggingService");
|
||||||
|
let pagination = require("../../services/PaginationService");
|
||||||
|
let SessionService = require("../../services/SessionService");
|
||||||
|
let JwtService = require("../../services/JwtService");
|
||||||
|
const ValidationService = require("../../services/ValidationService");
|
||||||
|
const PermissionService = require("../../services/PermissionService");
|
||||||
|
const UploadService = require("../../services/UploadService");
|
||||||
|
const AuthService = require("../../services/AuthService");
|
||||||
|
const db = require("../../models");
|
||||||
|
const helpers = require("../../core/helpers");
|
||||||
|
|
||||||
|
const role = 1;
|
||||||
|
|
||||||
|
app.get("/admin/actives/:num", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
let session = req.session;
|
||||||
|
let paginateListViewModel = require("../../view_models/actives_admin_list_paginate_view_model");
|
||||||
|
|
||||||
|
var viewModel = new paginateListViewModel(db.active, "Actives", session.success, session.error, "/admin/actives");
|
||||||
|
|
||||||
|
viewModel._column = ["ID", "Name", "Handle", "Description", "Variables scores", "Action"];
|
||||||
|
viewModel._readable_column = ["ID", "Name", "Handle", "Description", "Variables scores"];
|
||||||
|
|
||||||
|
const format = req.query.format ? req.query.format : "view";
|
||||||
|
const direction = req.query.direction ? req.query.direction : "ASC";
|
||||||
|
const per_page = req.query.per_page ? req.query.per_page : 10;
|
||||||
|
let order_by = req.query.order_by ? req.query.order_by : viewModel.get_field_column()[0];
|
||||||
|
let orderAssociations = [];
|
||||||
|
viewModel.set_order_by(order_by);
|
||||||
|
let joins = order_by.includes(".") ? order_by.split(".") : [];
|
||||||
|
order_by = order_by.includes(".") ? joins[joins.length - 1] : order_by;
|
||||||
|
if (joins.length > 0) {
|
||||||
|
for (let i = joins.length - 1; i > 0; i--) {
|
||||||
|
orderAssociations.push(`${joins[i - 1]}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check for flash messages
|
||||||
|
const flashMessageSuccess = req.flash("success");
|
||||||
|
if (flashMessageSuccess && flashMessageSuccess.length > 0) {
|
||||||
|
viewModel.success = flashMessageSuccess[0];
|
||||||
|
}
|
||||||
|
const flashMessageError = req.flash("error");
|
||||||
|
if (flashMessageError && flashMessageError.length > 0) {
|
||||||
|
viewModel.error = flashMessageError[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.set_id(req.query.id ? req.query.id : "");
|
||||||
|
viewModel.set_name(req.query.name ? req.query.name : "");
|
||||||
|
|
||||||
|
let where = helpers.filterEmptyFields({
|
||||||
|
id: viewModel.get_id(),
|
||||||
|
name: viewModel.get_name(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const count = await db.active._count(where, []);
|
||||||
|
|
||||||
|
viewModel.set_total_rows(count);
|
||||||
|
viewModel.set_per_page(+per_page);
|
||||||
|
viewModel.set_page(+req.params.num);
|
||||||
|
viewModel.set_query(req.query);
|
||||||
|
viewModel.set_sort_base_url(`/admin/actives/${+req.params.num}`);
|
||||||
|
viewModel.set_sort(direction);
|
||||||
|
|
||||||
|
const list = await db.active.getPaginated(viewModel.get_page() - 1 < 0 ? 0 : viewModel.get_page(), viewModel.get_per_page(), where, order_by, direction, orderAssociations);
|
||||||
|
|
||||||
|
viewModel.set_list(list);
|
||||||
|
|
||||||
|
if (format == "csv") {
|
||||||
|
const csv = viewModel.to_csv();
|
||||||
|
return res
|
||||||
|
.set({
|
||||||
|
"Content-Type": "text/csv",
|
||||||
|
"Content-Disposition": 'attachment; filename="export.csv"',
|
||||||
|
})
|
||||||
|
.send(csv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.render("admin/Actives", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Actives", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/admin/actives-add", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
const activesAdminAddViewModel = require("../../view_models/actives_admin_add_view_model");
|
||||||
|
|
||||||
|
const viewModel = new activesAdminAddViewModel(db.active, "Add active", "", "", "/admin/actives");
|
||||||
|
viewModel.output_variables = await db.output_variable.getAll();
|
||||||
|
res.render("admin/Add_Actives", viewModel);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/admin/actives-add", SessionService.verifySessionMiddleware(role, "admin"), ValidationService.validateInput({ name: "required", handle: "required" }), async function (req, res, next) {
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
const activesAdminAddViewModel = require("../../view_models/actives_admin_add_view_model");
|
||||||
|
|
||||||
|
const viewModel = new activesAdminAddViewModel(db.active, "Add active", "", "", "/admin/actives");
|
||||||
|
viewModel.output_variables = await db.output_variable.getAll();
|
||||||
|
|
||||||
|
// TODO use separate controller for image upload
|
||||||
|
// {{{upload_field_setter}}}
|
||||||
|
|
||||||
|
const { name, description, handle, ...rest } = req.body;
|
||||||
|
|
||||||
|
viewModel.form_fields = {
|
||||||
|
...viewModel.form_fields,
|
||||||
|
name,
|
||||||
|
handle,
|
||||||
|
description,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
viewModel.error = req.validationError;
|
||||||
|
return res.render("admin/Add_Actives", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
const data = await db.active.insert({ name, description, handle, variables_scores: JSON.stringify(rest) });
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Add_Actives", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
req.flash("success", "Active created successfully");
|
||||||
|
return res.redirect("/admin/actives/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Add_Actives", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/admin/actives-edit/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
const activesAdminEditViewModel = require("../../view_models/actives_admin_edit_view_model");
|
||||||
|
|
||||||
|
const viewModel = new activesAdminEditViewModel(db.active, "Edit active", "", "", "/admin/actives");
|
||||||
|
viewModel.output_variables = await db.output_variable.getAll();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = await db.active.getByPK(id);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
req.flash("error", "Active not found");
|
||||||
|
return res.redirect("/admin/actives/0");
|
||||||
|
}
|
||||||
|
const values = exists;
|
||||||
|
Object.keys(viewModel.form_fields).forEach((field) => {
|
||||||
|
viewModel.form_fields[field] = values[field] || "";
|
||||||
|
});
|
||||||
|
if (exists.variables_scores) {
|
||||||
|
const currentOutputVariablesScores = JSON.parse(exists.variables_scores);
|
||||||
|
Object.keys(currentOutputVariablesScores).forEach((varScore) => {
|
||||||
|
viewModel.form_fields[varScore] = currentOutputVariablesScores[varScore];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return res.render("admin/Edit_Actives", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Actives", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/admin/actives-edit/:id", SessionService.verifySessionMiddleware(role, "admin"), ValidationService.validateInput({ name: "required", handle: "required" }), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
const activesAdminEditViewModel = require("../../view_models/actives_admin_edit_view_model");
|
||||||
|
|
||||||
|
const viewModel = new activesAdminEditViewModel(db.active, "Edit active", "", "", "/admin/actives");
|
||||||
|
viewModel.form_fields = { variables_scores: "", name: "", id: "" };
|
||||||
|
viewModel.output_variables = await db.output_variable.getAll();
|
||||||
|
const { name, description, handle, ...rest } = req.body;
|
||||||
|
|
||||||
|
viewModel.form_fields = {
|
||||||
|
...viewModel.form_fields,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
handle,
|
||||||
|
};
|
||||||
|
|
||||||
|
delete viewModel.form_fields.id;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
viewModel.error = req.validationError;
|
||||||
|
return res.render("admin/Edit_Actives", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
const resourceExists = await db.active.getByPK(id);
|
||||||
|
if (!resourceExists) {
|
||||||
|
req.flash("error", "Active not found");
|
||||||
|
return res.redirect("/admin/actives/0");
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
let data = await db.active.edit({ name, description, handle, variables_scores: JSON.stringify(rest) }, id);
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Actives", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
req.flash("success", "Active edited successfully");
|
||||||
|
|
||||||
|
return res.redirect("/admin/actives/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Actives", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/admin/resync/actives", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
var config = {
|
||||||
|
method: "get",
|
||||||
|
url: `https://${process.env.SHOPIFY_API_KEY}:${process.env.SHOPIFY_API_PASSWORD}@${process.env.SHOPIFY_SITE}/admin/api/2021-10/products.json`,
|
||||||
|
headers: {},
|
||||||
|
};
|
||||||
|
const data = await axios(config).then((response) => response.data);
|
||||||
|
console.log(data.products);
|
||||||
|
for (const product of data.products) {
|
||||||
|
if (product.tags == "Personalized Cream" && product.title !== "Blank") {
|
||||||
|
const activeExists = await db.active.getByFields({ name: product.title });
|
||||||
|
if (activeExists) {
|
||||||
|
await db.active.edit(
|
||||||
|
{
|
||||||
|
handle: `https://localhost:3001/products/${product.handle}`,
|
||||||
|
},
|
||||||
|
activeExists.id
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await db.active.insert({
|
||||||
|
name: product.title,
|
||||||
|
handle: `https://localhost:3001/products/${product.handle}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
req.flash("success", "Actives resynced successfully");
|
||||||
|
return res.redirect("/admin/actives/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
req.flash("error", error.message);
|
||||||
|
return res.redirect("/admin/actives/0");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get(
|
||||||
|
"/admin/actives-view/:id",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
|
||||||
|
async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const activesAdminDetailViewModel = require("../../view_models/actives_admin_detail_view_model");
|
||||||
|
|
||||||
|
var viewModel = new activesAdminDetailViewModel(db.active, "Active details", "", "", "/admin/actives");
|
||||||
|
|
||||||
|
const data = await db.active.getByPK(id);
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Active not found";
|
||||||
|
viewModel.detail_fields = { ...viewModel.detail_fields, id: "N/A", name: "N/A", handle: "N/A", description: "N/A" };
|
||||||
|
} else {
|
||||||
|
viewModel.detail_fields = { ...viewModel.detail_fields, id: data["id"] || "N/A", name: data["name"] || "N/A", handle: data["handle"] || "N/A", description: data["description"] || "N/A" };
|
||||||
|
}
|
||||||
|
|
||||||
|
res.render("admin/View_Actives", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
viewModel.detail_fields = { ...viewModel.detail_fields, id: "N/A", name: "N/A", handle: "N/A", description: "N/A" };
|
||||||
|
res.render("admin/View_Actives", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get("/admin/actives-delete/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const activesAdminDeleteViewModel = require("../../view_models/actives_admin_delete_view_model");
|
||||||
|
|
||||||
|
const viewModel = new activesAdminDeleteViewModel(db.active);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = await db.active.getByPK(id);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
req.flash("error", "Active not found");
|
||||||
|
return res.redirect("/admin/actives/0");
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
await db.active.realDelete(id);
|
||||||
|
await db.answer.destroy({
|
||||||
|
where: {
|
||||||
|
answer: exists.name,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
req.flash("success", "Active was deleted successfully");
|
||||||
|
|
||||||
|
return res.redirect("/admin/actives/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
req.flash("error", error.message || "Something went wrong");
|
||||||
|
return res.redirect("/admin/actives/0");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
@@ -0,0 +1,614 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const app = require("express").Router();
|
||||||
|
const Sequelize = require("sequelize");
|
||||||
|
const logger = require("../../services/LoggingService");
|
||||||
|
let pagination = require("../../services/PaginationService");
|
||||||
|
let SessionService = require("../../services/SessionService");
|
||||||
|
let JwtService = require("../../services/JwtService");
|
||||||
|
const ValidationService = require("../../services/ValidationService");
|
||||||
|
const PermissionService = require("../../services/PermissionService");
|
||||||
|
const UploadService = require("../../services/UploadService");
|
||||||
|
const AuthService = require("../../services/AuthService");
|
||||||
|
const db = require("../../models");
|
||||||
|
const helpers = require("../../core/helpers");
|
||||||
|
|
||||||
|
const role = 1;
|
||||||
|
|
||||||
|
app.get("/admin/answers/:num", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
let session = req.session;
|
||||||
|
let paginateListViewModel = require("../../view_models/answers_admin_list_paginate_view_model");
|
||||||
|
|
||||||
|
var viewModel = new paginateListViewModel(db.answer, "Answers", session.success, session.error, "/admin/answers");
|
||||||
|
|
||||||
|
const format = req.query.format ? req.query.format : "view";
|
||||||
|
const direction = req.query.direction ? req.query.direction : "ASC";
|
||||||
|
const per_page = req.query.per_page ? req.query.per_page : 10;
|
||||||
|
// let order_by = req.query.order_by ? req.query.order_by : viewModel.get_field_column()[0];
|
||||||
|
let order_by = [
|
||||||
|
["question", "quiz_id", direction],
|
||||||
|
["question", "order", direction],
|
||||||
|
["question_id", direction],
|
||||||
|
["order", direction],
|
||||||
|
];
|
||||||
|
// Check for flash messages
|
||||||
|
const flashMessageSuccess = req.flash("success");
|
||||||
|
if (flashMessageSuccess && flashMessageSuccess.length > 0) {
|
||||||
|
viewModel.success = flashMessageSuccess[0];
|
||||||
|
}
|
||||||
|
const flashMessageError = req.flash("error");
|
||||||
|
if (flashMessageError && flashMessageError.length > 0) {
|
||||||
|
viewModel.error = flashMessageError[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.set_id(req.query.id ? req.query.id : "");
|
||||||
|
viewModel.set_question_id(req.query.question_id ? req.query.question_id : "");
|
||||||
|
|
||||||
|
let where = helpers.filterEmptyFields({
|
||||||
|
id: viewModel.get_id(),
|
||||||
|
question_id: viewModel.get_question_id(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const count = await db.answer._count(where, [{ all: true, nested: true }]);
|
||||||
|
|
||||||
|
viewModel.set_total_rows(count);
|
||||||
|
viewModel.set_per_page(+per_page);
|
||||||
|
viewModel.set_page(+req.params.num);
|
||||||
|
viewModel.set_query(req.query);
|
||||||
|
viewModel.set_sort_base_url(`/admin/answers/${+req.params.num}`);
|
||||||
|
viewModel.set_sort(direction);
|
||||||
|
|
||||||
|
const list = await db.answer.getPaginatedV2(viewModel.get_page() - 1 < 0 ? 0 : viewModel.get_page(), viewModel.get_per_page(), where, order_by, direction, [{ all: true, nested: true }]);
|
||||||
|
|
||||||
|
viewModel.set_list(list);
|
||||||
|
|
||||||
|
viewModel.question = await db.question;
|
||||||
|
viewModel.image = await db.image;
|
||||||
|
|
||||||
|
if (format == "csv") {
|
||||||
|
const csv = viewModel.to_csv();
|
||||||
|
return res
|
||||||
|
.set({
|
||||||
|
"Content-Type": "text/csv",
|
||||||
|
"Content-Disposition": 'attachment; filename="export.csv"',
|
||||||
|
})
|
||||||
|
.send(csv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.render("admin/Answers", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Answers", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/admin/answers-add", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
const answersAdminAddViewModel = require("../../view_models/answers_admin_add_view_model");
|
||||||
|
|
||||||
|
const viewModel = new answersAdminAddViewModel(db.answer, "Add answer", "", "", "/admin/answers");
|
||||||
|
viewModel.questions = await db.question.getAll({
|
||||||
|
type: {
|
||||||
|
[Sequelize.Op.notIn]: [1, 2, 3],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
viewModel.actives = await db.active.getAll();
|
||||||
|
res.render("admin/Add_Answers", viewModel);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post(
|
||||||
|
"/admin/answers-add",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
ValidationService.validateInput({ question_id: "required", order: "required" }, { "question_id.required": "QuestionId is required", "order.required": "Order is required" }),
|
||||||
|
async function (req, res, next) {
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
const addedFromQuestion = req.query.question;
|
||||||
|
const answersAdminAddViewModel = require("../../view_models/answers_admin_add_view_model");
|
||||||
|
|
||||||
|
const viewModel = new answersAdminAddViewModel(db.answer, "Add answer", "", "", "/admin/answers");
|
||||||
|
viewModel.questions = await db.question.getAll({
|
||||||
|
type: {
|
||||||
|
[Sequelize.Op.notIn]: [1, 2, 3],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
viewModel.actives = await db.active.getAll();
|
||||||
|
|
||||||
|
const {
|
||||||
|
question_id,
|
||||||
|
answer,
|
||||||
|
answer_value,
|
||||||
|
hide_answer,
|
||||||
|
order,
|
||||||
|
explaination,
|
||||||
|
image_id,
|
||||||
|
response_header,
|
||||||
|
response_body,
|
||||||
|
// response_arguments,
|
||||||
|
black_list_actives,
|
||||||
|
} = req.body;
|
||||||
|
|
||||||
|
viewModel.form_fields = {
|
||||||
|
...viewModel.form_fields,
|
||||||
|
question_id,
|
||||||
|
answer,
|
||||||
|
answer_value,
|
||||||
|
hide_answer,
|
||||||
|
order,
|
||||||
|
explaination,
|
||||||
|
image_id,
|
||||||
|
response_header,
|
||||||
|
response_body,
|
||||||
|
// response_arguments,
|
||||||
|
black_list_actives,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
viewModel.error = req.validationError;
|
||||||
|
if (addedFromQuestion) {
|
||||||
|
req.flash("error", req.validationError);
|
||||||
|
return res.redirect(`/admin/questions-edit/${addedFromQuestion}`);
|
||||||
|
}
|
||||||
|
return res.render("admin/Add_Answers", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
const data = await db.answer.insert(
|
||||||
|
helpers.filterEmptyFields({
|
||||||
|
question_id,
|
||||||
|
answer,
|
||||||
|
answer_value,
|
||||||
|
hide_answer,
|
||||||
|
order,
|
||||||
|
explaination,
|
||||||
|
image_id,
|
||||||
|
response_header,
|
||||||
|
response_body,
|
||||||
|
// response_arguments,
|
||||||
|
black_list_actives: !Array.isArray(black_list_actives) ? JSON.stringify([black_list_actives]) : JSON.stringify(black_list_actives),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Add_Answers", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.activity_log.insert({
|
||||||
|
action: "ADD",
|
||||||
|
name: "Admin_answer_controller.js",
|
||||||
|
portal: "admin",
|
||||||
|
data: JSON.stringify({
|
||||||
|
question_id,
|
||||||
|
answer,
|
||||||
|
answer_value,
|
||||||
|
hide_answer,
|
||||||
|
order,
|
||||||
|
explaination,
|
||||||
|
image_id,
|
||||||
|
response_header,
|
||||||
|
response_body,
|
||||||
|
// response_arguments,
|
||||||
|
black_list_actives: !Array.isArray(black_list_actives) ? JSON.stringify([black_list_actives]) : JSON.stringify(black_list_actives),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
if (addedFromQuestion) {
|
||||||
|
req.flash("success", "Answer created successfully");
|
||||||
|
return res.redirect(`/admin/questions-edit/${addedFromQuestion}`);
|
||||||
|
}
|
||||||
|
req.flash("success", "Answer created successfully");
|
||||||
|
return res.redirect("/admin/answers/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
if (addedFromQuestion) {
|
||||||
|
req.flash("error", viewModel.error);
|
||||||
|
return res.redirect(`/admin/questions-edit/${addedFromQuestion}`);
|
||||||
|
}
|
||||||
|
return res.render("admin/Add_Answers", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get("/admin/answers-edit/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
const answersAdminEditViewModel = require("../../view_models/answers_admin_edit_view_model");
|
||||||
|
|
||||||
|
const viewModel = new answersAdminEditViewModel(db.answer, "Edit answer", "", "", "/admin/answers");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = await db.answer.findOne({
|
||||||
|
where: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
include: [{ all: true, nested: true }],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
req.flash("error", "Answer not found");
|
||||||
|
return res.redirect("/admin/answers/0");
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.answer = exists;
|
||||||
|
viewModel.question = await db.question.getByPK(exists.question_id);
|
||||||
|
viewModel.questions = await db.question.getAll({
|
||||||
|
type: {
|
||||||
|
[Sequelize.Op.notIn]: [1, 2, 3],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
viewModel.actives = await db.active.getAll();
|
||||||
|
return res.render("admin/Edit_Answers", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Answers", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post(
|
||||||
|
"/admin/answers-edit/:id",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
ValidationService.validateInput(
|
||||||
|
{ question_id: "required", answer: "required", order: "required" },
|
||||||
|
{ "question_id.required": "QuestionId is required", "answer.required": "Answer is required", "order.required": "Order is required" }
|
||||||
|
),
|
||||||
|
async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
const answersAdminEditViewModel = require("../../view_models/answers_admin_edit_view_model");
|
||||||
|
|
||||||
|
const viewModel = new answersAdminEditViewModel(db.answer, "Edit answer", "", "", "/admin/answers");
|
||||||
|
viewModel.questions = await db.question.getAll({
|
||||||
|
type: {
|
||||||
|
[Sequelize.Op.notIn]: [1, 2, 3],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
viewModel.actives = await db.active.getAll();
|
||||||
|
const {
|
||||||
|
question_id,
|
||||||
|
answer,
|
||||||
|
answer_value,
|
||||||
|
hide_answer,
|
||||||
|
order,
|
||||||
|
explaination,
|
||||||
|
image_id,
|
||||||
|
response_header,
|
||||||
|
response_body,
|
||||||
|
// response_arguments,
|
||||||
|
black_list_actives,
|
||||||
|
} = req.body;
|
||||||
|
|
||||||
|
viewModel.form_fields = {
|
||||||
|
...viewModel.form_fields,
|
||||||
|
question_id,
|
||||||
|
answer,
|
||||||
|
answer_value,
|
||||||
|
hide_answer,
|
||||||
|
order,
|
||||||
|
explaination,
|
||||||
|
image_id,
|
||||||
|
response_header,
|
||||||
|
response_body,
|
||||||
|
// response_arguments,
|
||||||
|
black_list_actives,
|
||||||
|
};
|
||||||
|
|
||||||
|
delete viewModel.form_fields.id;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
viewModel.error = req.validationError;
|
||||||
|
return res.render("admin/Edit_Answers", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
const resourceExists = await db.answer.getByPK(id);
|
||||||
|
if (!resourceExists) {
|
||||||
|
req.flash("error", "Answer not found");
|
||||||
|
return res.redirect("/admin/answers/0");
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.question = await db.question.getByPK(resourceExists.question_id);
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
let data = await db.answer.edit(
|
||||||
|
helpers.filterEmptyFields({
|
||||||
|
question_id,
|
||||||
|
answer,
|
||||||
|
answer_value,
|
||||||
|
hide_answer,
|
||||||
|
order,
|
||||||
|
explaination,
|
||||||
|
image_id,
|
||||||
|
response_header,
|
||||||
|
response_body,
|
||||||
|
// response_arguments,
|
||||||
|
black_list_actives: JSON.stringify(black_list_actives),
|
||||||
|
}),
|
||||||
|
id
|
||||||
|
);
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Answers", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resourceExists.question) {
|
||||||
|
data = await db.question.edit(helpers.filterEmptyFields({}), resourceExists.question.id);
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Answers", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.activity_log.insert({
|
||||||
|
action: "EDIT",
|
||||||
|
name: "Admin_answer_controller.js",
|
||||||
|
portal: "admin",
|
||||||
|
data: JSON.stringify({
|
||||||
|
question_id,
|
||||||
|
answer,
|
||||||
|
answer_value,
|
||||||
|
order,
|
||||||
|
explaination,
|
||||||
|
image_id,
|
||||||
|
response_header,
|
||||||
|
response_body,
|
||||||
|
// response_arguments,
|
||||||
|
black_list_actives: JSON.stringify(black_list_actives),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
req.flash("success", "Answer edited successfully");
|
||||||
|
|
||||||
|
return res.redirect("/admin/answers/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Answers", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get(
|
||||||
|
"/admin/answers-view/:id",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
|
||||||
|
async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const answersAdminDetailViewModel = require("../../view_models/answers_admin_detail_view_model");
|
||||||
|
|
||||||
|
var viewModel = new answersAdminDetailViewModel(db.answer, "Answer details", "", "", "/admin/answers");
|
||||||
|
|
||||||
|
const data = await db.answer.findOne({
|
||||||
|
where: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
include: [{ all: true, nested: true }],
|
||||||
|
});
|
||||||
|
|
||||||
|
data["question.note_type"] = db.question.note_type_mapping()[data.question.note_type];
|
||||||
|
data["question.target"] = db.question.target_mapping()[data.question.target];
|
||||||
|
data["question.type"] = db.question.type_mapping()[data.question.type];
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Answer not found";
|
||||||
|
viewModel.detail_fields = {
|
||||||
|
...viewModel.detail_fields,
|
||||||
|
id: "N/A",
|
||||||
|
question_id: "N/A",
|
||||||
|
"question.question": "N/A",
|
||||||
|
answer: "N/A",
|
||||||
|
answer_value: "N/A",
|
||||||
|
order: "N/A",
|
||||||
|
explaination: "N/A",
|
||||||
|
image_id: "N/A",
|
||||||
|
response_header: "N/A",
|
||||||
|
response_body: "N/A",
|
||||||
|
response_arguments: "N/A",
|
||||||
|
black_list_actives: "N/A",
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
viewModel.answer = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.render("admin/View_Answers", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
viewModel.detail_fields = {
|
||||||
|
...viewModel.detail_fields,
|
||||||
|
id: "N/A",
|
||||||
|
question_id: "N/A",
|
||||||
|
"question.question": "N/A",
|
||||||
|
answer: "N/A",
|
||||||
|
answer_value: "N/A",
|
||||||
|
order: "N/A",
|
||||||
|
explaination: "N/A",
|
||||||
|
image_id: "N/A",
|
||||||
|
response_header: "N/A",
|
||||||
|
response_body: "N/A",
|
||||||
|
response_arguments: "N/A",
|
||||||
|
black_list_actives: "N/A",
|
||||||
|
};
|
||||||
|
res.render("admin/View_Answers", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get("/admin/answers-delete/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const answersAdminDeleteViewModel = require("../../view_models/answers_admin_delete_view_model");
|
||||||
|
|
||||||
|
const viewModel = new answersAdminDeleteViewModel(db.answer);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = await db.answer.getByPK(id);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
req.flash("error", "Answer not found");
|
||||||
|
return res.redirect("/admin/answers/0");
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
await db.answer.realDelete(id);
|
||||||
|
|
||||||
|
await db.activity_log.insert({
|
||||||
|
action: "DELETE",
|
||||||
|
name: "Admin_answer_controller.js",
|
||||||
|
portal: "admin",
|
||||||
|
data: JSON.stringify(exists),
|
||||||
|
});
|
||||||
|
|
||||||
|
req.flash("success", "Answer was deleted successfully");
|
||||||
|
|
||||||
|
return res.redirect("/admin/answers/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
req.flash("error", error.message || "Something went wrong");
|
||||||
|
return res.redirect("/admin/answers/0");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// APIS
|
||||||
|
|
||||||
|
app.get("/admin/api/answers", JwtService.verifyTokenMiddleware(role), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
const user_id = req.user_id;
|
||||||
|
const session = req.session;
|
||||||
|
let listViewModel = require("../../view_models/answers_admin_list_paginate_view_model");
|
||||||
|
let viewModel = new listViewModel(db.answer, "Answers", session.success, session.error, "/admin/answers");
|
||||||
|
const direction = req.query.direction ? req.query.direction : "ASC";
|
||||||
|
const page = req.query.page ? parseInt(req.query.page) : 1;
|
||||||
|
const limit = req.query.limit ? parseInt(req.query.limit) : 10;
|
||||||
|
const offset = (page - 1) * limit;
|
||||||
|
let order_by = req.query.order_by ? req.query.order_by : viewModel.get_field_column()[0];
|
||||||
|
let orderAssociations = [];
|
||||||
|
viewModel.set_order_by(order_by);
|
||||||
|
let joins = order_by.includes(".") ? order_by.split(".") : [];
|
||||||
|
order_by = order_by.includes(".") ? joins[joins.length - 1] : order_by;
|
||||||
|
if (joins.length > 0) {
|
||||||
|
for (let i = joins.length - 1; i > 0; i--) {
|
||||||
|
orderAssociations.push(`${joins[i - 1]}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.set_id(req.query.id ? req.query.id : "");
|
||||||
|
viewModel.set_question_id(req.query.question_id ? req.query.question_id : "");
|
||||||
|
|
||||||
|
let where = helpers.filterEmptyFields({
|
||||||
|
id: viewModel.get_id(),
|
||||||
|
question_id: viewModel.get_question_id(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let associatedWhere = helpers.filterEmptyFields({});
|
||||||
|
const isAssociationRequired = Object.keys(associatedWhere).length > 0 ? true : false;
|
||||||
|
|
||||||
|
let include = [{ model: db.question, where: associatedWhere, required: isAssociationRequired, as: "question" }];
|
||||||
|
|
||||||
|
const { rows: allItems, count } = await db.answer.findAndCountAll({
|
||||||
|
where: where,
|
||||||
|
limit: limit == 0 ? null : limit,
|
||||||
|
offset: offset,
|
||||||
|
include: include,
|
||||||
|
distinct: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = {
|
||||||
|
items: allItems,
|
||||||
|
page,
|
||||||
|
nextPage: count > offset + limit ? page + 1 : false,
|
||||||
|
retrievedCount: allItems.length,
|
||||||
|
fullCount: count,
|
||||||
|
};
|
||||||
|
|
||||||
|
return res.status(201).json({ success: true, data: response });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return res.status(500).json({ success: false, message: error.message || "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post(
|
||||||
|
"/admin/answers-bulk-edit/:id",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
ValidationService.validateInput({ answer: "required", order: "required" }, { "answer.required": "Answer is required", "order.required": "Order is required" }),
|
||||||
|
async function (req, res, next) {
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
const questionId = req.params.id;
|
||||||
|
const { ids, answer, answer_value, hide_answer, order, explaination, image_id, response_header, response_body } = req.body;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
req.flash("error", req.validationError);
|
||||||
|
return res.redirect(`/admin/questions-edit/${questionId}`);
|
||||||
|
}
|
||||||
|
for (let i = 0; i < ids.length; i++) {
|
||||||
|
await db.answer.edit(
|
||||||
|
helpers.filterEmptyFields({
|
||||||
|
answer: answer ? answer[i] : null,
|
||||||
|
answer_value: answer_value ? answer_value[i] : null,
|
||||||
|
hide_answer: hide_answer ? hide_answer[i] : null,
|
||||||
|
// order: order ? order[i] : null,
|
||||||
|
order: i + 1,
|
||||||
|
explaination: explaination ? explaination[i] : null,
|
||||||
|
image_id: image_id ? image_id[i] : null,
|
||||||
|
response_header: response_header ? response_header[i] : null,
|
||||||
|
response_body: response_body ? response_body[i] : null,
|
||||||
|
black_list_actives: req.body[`black_list_actives_${ids[i]}`] ? JSON.stringify(req.body[`black_list_actives_${ids[i]}`]) : null,
|
||||||
|
}),
|
||||||
|
ids[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// req.flash("success", "Answers edited successfully");
|
||||||
|
// return res.redirect(`/admin/questions-edit/${questionId}`);
|
||||||
|
return res.json({ success: true, message: "Answers edited successfully" });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
req.flash("error", error.message || "Something went wrong. please contact admin.");
|
||||||
|
return res.redirect(`/admin/questions-edit/${questionId}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get("/admin/question/:question/answer-delete/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let { id, question } = req.params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = await db.answer.getByPK(id);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
req.flash("error", "Answer not found");
|
||||||
|
return res.redirect("/admin/questions-edit/" + question);
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.answer.realDelete(id);
|
||||||
|
|
||||||
|
req.flash("success", "Answer was deleted successfully");
|
||||||
|
return res.redirect("/admin/questions-edit/" + question);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
req.flash("error", error.message || "Something went wrong");
|
||||||
|
return res.redirect("/admin/questions-edit/" + question);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const app = require("express").Router();
|
||||||
|
const Sequelize = require("sequelize");
|
||||||
|
const logger = require("../../services/LoggingService");
|
||||||
|
let pagination = require("../../services/PaginationService");
|
||||||
|
let SessionService = require("../../services/SessionService");
|
||||||
|
let JwtService = require("../../services/JwtService");
|
||||||
|
const ValidationService = require("../../services/ValidationService");
|
||||||
|
const PermissionService = require("../../services/PermissionService");
|
||||||
|
const UploadService = require("../../services/UploadService");
|
||||||
|
const AuthService = require("../../services/AuthService");
|
||||||
|
const db = require("../../models");
|
||||||
|
const helpers = require("../../core/helpers");
|
||||||
|
|
||||||
|
const role = 1;
|
||||||
|
|
||||||
|
app.get("/admin/orders/:num", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
let session = req.session;
|
||||||
|
let paginateListViewModel = require("../../view_models/orders_admin_list_paginate_view_model");
|
||||||
|
|
||||||
|
var viewModel = new paginateListViewModel(db.order, "Orders", session.success, session.error, "/admin/orders");
|
||||||
|
|
||||||
|
const format = req.query.format ? req.query.format : "view";
|
||||||
|
const direction = req.query.direction ? req.query.direction : "DESC";
|
||||||
|
const per_page = req.query.per_page ? req.query.per_page : 10;
|
||||||
|
let order_by = req.query.order_by ? req.query.order_by : viewModel.get_field_column()[0];
|
||||||
|
let orderAssociations = [];
|
||||||
|
viewModel.set_order_by(order_by);
|
||||||
|
let joins = order_by.includes(".") ? order_by.split(".") : [];
|
||||||
|
order_by = order_by.includes(".") ? joins[joins.length - 1] : order_by;
|
||||||
|
if (joins.length > 0) {
|
||||||
|
for (let i = joins.length - 1; i > 0; i--) {
|
||||||
|
orderAssociations.push(`${joins[i - 1]}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check for flash messages
|
||||||
|
const flashMessageSuccess = req.flash("success");
|
||||||
|
if (flashMessageSuccess && flashMessageSuccess.length > 0) {
|
||||||
|
viewModel.success = flashMessageSuccess[0];
|
||||||
|
}
|
||||||
|
const flashMessageError = req.flash("error");
|
||||||
|
if (flashMessageError && flashMessageError.length > 0) {
|
||||||
|
viewModel.error = flashMessageError[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.set_id(req.query.id ? req.query.id : "");
|
||||||
|
viewModel.set_customer_shopify_id(req.query.customer_shopify_id ? req.query.customer_shopify_id : "");
|
||||||
|
viewModel.set_shopify_id(req.query.shopify_id ? req.query.shopify_id : "");
|
||||||
|
viewModel.set_financial_status(req.query.financial_status ? req.query.financial_status : "");
|
||||||
|
viewModel.set_fulfillment_status(req.query.fulfillment_status ? req.query.fulfillment_status : "");
|
||||||
|
|
||||||
|
let where = helpers.filterEmptyFields({
|
||||||
|
id: viewModel.get_id(),
|
||||||
|
customer_shopify_id: viewModel.get_customer_shopify_id(),
|
||||||
|
shopify_id: viewModel.get_shopify_id(),
|
||||||
|
financial_status: viewModel.get_financial_status(),
|
||||||
|
fulfillment_status: viewModel.get_fulfillment_status(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const count = await db.order._count(where, []);
|
||||||
|
|
||||||
|
viewModel.set_total_rows(count);
|
||||||
|
viewModel.set_per_page(+per_page);
|
||||||
|
viewModel.set_page(+req.params.num);
|
||||||
|
viewModel.set_query(req.query);
|
||||||
|
viewModel.set_sort_base_url(`/admin/orders/${+req.params.num}`);
|
||||||
|
viewModel.set_sort(direction);
|
||||||
|
|
||||||
|
const list = await db.order.getPaginated(viewModel.get_page() - 1 < 0 ? 0 : viewModel.get_page(), viewModel.get_per_page(), where, order_by, direction, orderAssociations);
|
||||||
|
|
||||||
|
viewModel.set_list(list);
|
||||||
|
|
||||||
|
if (format == "csv") {
|
||||||
|
const csv = viewModel.to_csv();
|
||||||
|
return res
|
||||||
|
.set({
|
||||||
|
"Content-Type": "text/csv",
|
||||||
|
"Content-Disposition": 'attachment; filename="export.csv"',
|
||||||
|
})
|
||||||
|
.send(csv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (format != 'view') {
|
||||||
|
// res.json(viewModel.to_json());
|
||||||
|
// } else {
|
||||||
|
// }
|
||||||
|
|
||||||
|
return res.render("admin/Orders", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Orders", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// APIS
|
||||||
|
|
||||||
|
app.get("/admin/api/orders", JwtService.verifyTokenMiddleware(role), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
const user_id = req.user_id;
|
||||||
|
const session = req.session;
|
||||||
|
let listViewModel = require("../../view_models/orders_admin_list_paginate_view_model");
|
||||||
|
let viewModel = new listViewModel(db.order, "Orders", session.success, session.error, "/admin/orders");
|
||||||
|
const direction = req.query.direction ? req.query.direction : "ASC";
|
||||||
|
const page = req.query.page ? parseInt(req.query.page) : 1;
|
||||||
|
const limit = req.query.limit ? parseInt(req.query.limit) : 10;
|
||||||
|
const offset = (page - 1) * limit;
|
||||||
|
let order_by = req.query.order_by ? req.query.order_by : viewModel.get_field_column()[0];
|
||||||
|
let orderAssociations = [];
|
||||||
|
viewModel.set_order_by(order_by);
|
||||||
|
let joins = order_by.includes(".") ? order_by.split(".") : [];
|
||||||
|
order_by = order_by.includes(".") ? joins[joins.length - 1] : order_by;
|
||||||
|
if (joins.length > 0) {
|
||||||
|
for (let i = joins.length - 1; i > 0; i--) {
|
||||||
|
orderAssociations.push(`${joins[i - 1]}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.set_id(req.query.id ? req.query.id : "");
|
||||||
|
viewModel.set_customer_shopify_id(req.query.customer_shopify_id ? req.query.customer_shopify_id : "");
|
||||||
|
viewModel.set_shopify_id(req.query.shopify_id ? req.query.shopify_id : "");
|
||||||
|
viewModel.set_financial_status(req.query.financial_status ? req.query.financial_status : "");
|
||||||
|
viewModel.set_fulfillment_status(req.query.fulfillment_status ? req.query.fulfillment_status : "");
|
||||||
|
|
||||||
|
let where = helpers.filterEmptyFields({
|
||||||
|
id: viewModel.get_id(),
|
||||||
|
customer_shopify_id: viewModel.get_customer_shopify_id(),
|
||||||
|
shopify_id: viewModel.get_shopify_id(),
|
||||||
|
financial_status: viewModel.get_financial_status(),
|
||||||
|
fulfillment_status: viewModel.get_fulfillment_status(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let include = [];
|
||||||
|
|
||||||
|
const { rows: allItems, count } = await db.order.findAndCountAll({
|
||||||
|
where: where,
|
||||||
|
limit: limit == 0 ? null : limit,
|
||||||
|
offset: offset,
|
||||||
|
include: include,
|
||||||
|
distinct: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = {
|
||||||
|
items: allItems,
|
||||||
|
page,
|
||||||
|
nextPage: count > offset + limit ? page + 1 : false,
|
||||||
|
retrievedCount: allItems.length,
|
||||||
|
fullCount: count,
|
||||||
|
};
|
||||||
|
|
||||||
|
return res.status(201).json({ success: true, data: response });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return res.status(500).json({ success: false, message: error.message || "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/v1/api/order/customer", async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
const { id } = req.query;
|
||||||
|
console.log(id);
|
||||||
|
if (!id) {
|
||||||
|
return res.status(400).json({ success: false, message: "Id not valid." });
|
||||||
|
}
|
||||||
|
const orders = await db.order.findAll({ where: { customer_shopify_id: id }, order: [["updated_at", "DESC"]] });
|
||||||
|
console.log(orders);
|
||||||
|
if (!orders || !orders.length) return res.status(404).json({ success: false, message: "Customer doesn't have any orders." });
|
||||||
|
const answers = orders[0].answers ? JSON.parse(orders[0].answers) : [];
|
||||||
|
|
||||||
|
return res.status(201).json({ success: true, data: answers });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return res.status(500).json({ success: false, message: error.message || "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
@@ -0,0 +1,358 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const app = require("express").Router();
|
||||||
|
// const Sequelize = require("sequelize");
|
||||||
|
// const logger = require("../../services/LoggingService");
|
||||||
|
// let pagination = require("../../services/PaginationService");
|
||||||
|
// let JwtService = require("../../services/JwtService");
|
||||||
|
let SessionService = require("../../services/SessionService");
|
||||||
|
const ValidationService = require("../../services/ValidationService");
|
||||||
|
// const PermissionService = require("../../services/PermissionService");
|
||||||
|
// const UploadService = require("../../services/UploadService");
|
||||||
|
// const AuthService = require("../../services/AuthService");
|
||||||
|
const db = require("../../models");
|
||||||
|
const helpers = require("../../core/helpers");
|
||||||
|
|
||||||
|
const role = 1;
|
||||||
|
|
||||||
|
app.get("/admin/output-variables/:num", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
let session = req.session;
|
||||||
|
let paginateListViewModel = require("../../view_models/output_variables_admin_list_paginate_view_model");
|
||||||
|
|
||||||
|
var viewModel = new paginateListViewModel(db.output_variable, "Output variables", session.success, session.error, "/admin/output-variables");
|
||||||
|
|
||||||
|
const format = req.query.format ? req.query.format : "view";
|
||||||
|
const direction = req.query.direction ? req.query.direction : "ASC";
|
||||||
|
const per_page = req.query.per_page ? req.query.per_page : 10;
|
||||||
|
let order_by = req.query.order_by ? req.query.order_by : viewModel.get_field_column()[0];
|
||||||
|
let orderAssociations = [];
|
||||||
|
viewModel.set_order_by(order_by);
|
||||||
|
let joins = order_by.includes(".") ? order_by.split(".") : [];
|
||||||
|
order_by = order_by.includes(".") ? joins[joins.length - 1] : order_by;
|
||||||
|
if (joins.length > 0) {
|
||||||
|
for (let i = joins.length - 1; i > 0; i--) {
|
||||||
|
orderAssociations.push(`${joins[i - 1]}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check for flash messages
|
||||||
|
const flashMessageSuccess = req.flash("success");
|
||||||
|
if (flashMessageSuccess && flashMessageSuccess.length > 0) {
|
||||||
|
viewModel.success = flashMessageSuccess[0];
|
||||||
|
}
|
||||||
|
const flashMessageError = req.flash("error");
|
||||||
|
if (flashMessageError && flashMessageError.length > 0) {
|
||||||
|
viewModel.error = flashMessageError[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.set_id(req.query.id ? req.query.id : "");
|
||||||
|
viewModel.set_name(req.query.name ? req.query.name : "");
|
||||||
|
|
||||||
|
let where = helpers.filterEmptyFields({
|
||||||
|
id: viewModel.get_id(),
|
||||||
|
name: viewModel.get_name(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const count = await db.output_variable._count(where, []);
|
||||||
|
|
||||||
|
viewModel.set_total_rows(count);
|
||||||
|
viewModel.set_per_page(+per_page);
|
||||||
|
viewModel.set_page(+req.params.num);
|
||||||
|
viewModel.set_query(req.query);
|
||||||
|
viewModel.set_sort_base_url(`/admin/output-variables/${+req.params.num}`);
|
||||||
|
viewModel.set_sort(direction);
|
||||||
|
|
||||||
|
const list = await db.output_variable.getPaginated(viewModel.get_page() - 1 < 0 ? 0 : viewModel.get_page(), viewModel.get_per_page(), where, order_by, direction, orderAssociations);
|
||||||
|
for (const item of list) {
|
||||||
|
if (item.active_list) {
|
||||||
|
const actives = await db.active.findAll({
|
||||||
|
where: {
|
||||||
|
id: JSON.parse(item.active_list),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
item.active_list = actives.map((active) => {
|
||||||
|
return { name: active.name, id: active.id };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
viewModel.set_list(list);
|
||||||
|
|
||||||
|
if (format == "csv") {
|
||||||
|
const csv = viewModel.to_csv();
|
||||||
|
return res
|
||||||
|
.set({
|
||||||
|
"Content-Type": "text/csv",
|
||||||
|
"Content-Disposition": 'attachment; filename="export.csv"',
|
||||||
|
})
|
||||||
|
.send(csv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (format != 'view') {
|
||||||
|
// res.json(viewModel.to_json());
|
||||||
|
// } else {
|
||||||
|
// }
|
||||||
|
|
||||||
|
return res.render("admin/Output_variables", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Output_variables", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/admin/output-variables-add", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
const outputVariablesAdminAddViewModel = require("../../view_models/output_variables_admin_add_view_model");
|
||||||
|
|
||||||
|
const viewModel = new outputVariablesAdminAddViewModel(db.output_variable, "Add output variable", "", "", "/admin/output-variables");
|
||||||
|
viewModel.actives = await db.active.getAll();
|
||||||
|
res.render("admin/Add_Output_variables", viewModel);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post(
|
||||||
|
"/admin/output-variables-add",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
ValidationService.validateInput({ name: "required", active_list: "required" }, { "name.required": "Name is required", "active_list.required": "ActiveList is required" }),
|
||||||
|
async function (req, res, next) {
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
const outputVariablesAdminAddViewModel = require("../../view_models/output_variables_admin_add_view_model");
|
||||||
|
|
||||||
|
const viewModel = new outputVariablesAdminAddViewModel(db.output_variable, "Add output variable", "", "", "/admin/output-variables");
|
||||||
|
viewModel.actives = await db.active.getAll();
|
||||||
|
|
||||||
|
const { name, active_list, ranges, responses } = req.body;
|
||||||
|
let ranges_response = [],
|
||||||
|
i = 0;
|
||||||
|
if (Array.isArray(ranges) && Array.isArray(responses)) {
|
||||||
|
for (const range of ranges) {
|
||||||
|
let tempObj = {};
|
||||||
|
tempObj[range] = responses[i];
|
||||||
|
ranges_response.push(tempObj);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ranges_response.push({
|
||||||
|
[ranges]: responses,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
viewModel.form_fields = {
|
||||||
|
...viewModel.form_fields,
|
||||||
|
name,
|
||||||
|
active_list,
|
||||||
|
ranges_response,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
viewModel.error = req.validationError;
|
||||||
|
return res.render("admin/Add_Output_variables", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
const data = await db.output_variable.insert({ name, active_list: JSON.stringify(active_list), ranges_response: JSON.stringify(ranges_response) });
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Add_Output_variables", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
req.flash("success", "Output variable created successfully");
|
||||||
|
return res.redirect("/admin/output-variables/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Add_Output_variables", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get("/admin/output-variables-edit/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
const outputVariablesAdminEditViewModel = require("../../view_models/output_variables_admin_edit_view_model");
|
||||||
|
|
||||||
|
const viewModel = new outputVariablesAdminEditViewModel(db.output_variable, "Edit output variable", "", "", "/admin/output-variables");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = await db.output_variable.getByPK(id);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
req.flash("error", "Output variable not found");
|
||||||
|
return res.redirect("/admin/output-variables/0");
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.outputVariable = exists;
|
||||||
|
viewModel.actives = await db.active.getAll();
|
||||||
|
return res.render("admin/Edit_Output_variables", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Output_variables", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post(
|
||||||
|
"/admin/output-variables-edit/:id",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
ValidationService.validateInput({ name: "required" }, { "name.required": "Name is required" }),
|
||||||
|
async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
const outputVariablesAdminEditViewModel = require("../../view_models/output_variables_admin_edit_view_model");
|
||||||
|
|
||||||
|
const viewModel = new outputVariablesAdminEditViewModel(db.output_variable, "Edit output variable", "", "", "/admin/output-variables");
|
||||||
|
|
||||||
|
const { name, active_list, ranges, responses } = req.body;
|
||||||
|
let ranges_response = [],
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
if (Array.isArray(ranges) && Array.isArray(responses)) {
|
||||||
|
for (const range of ranges) {
|
||||||
|
let tempObj = {};
|
||||||
|
tempObj[range] = responses[i];
|
||||||
|
ranges_response.push(tempObj);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ranges_response.push({
|
||||||
|
[ranges]: responses,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ranges_response = JSON.stringify(ranges_response);
|
||||||
|
viewModel.form_fields = {
|
||||||
|
...viewModel.form_fields,
|
||||||
|
name,
|
||||||
|
active_list,
|
||||||
|
ranges_response,
|
||||||
|
};
|
||||||
|
delete viewModel.form_fields.id;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
viewModel.error = req.validationError;
|
||||||
|
return res.render("admin/Edit_Output_variables", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
const resourceExists = await db.output_variable.getByPK(id);
|
||||||
|
if (!resourceExists) {
|
||||||
|
req.flash("error", "Output variable not found");
|
||||||
|
return res.redirect("/admin/output-variables/0");
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.outputVariable = resourceExists;
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
let data = await db.output_variable.edit(
|
||||||
|
{
|
||||||
|
name,
|
||||||
|
active_list: active_list ? JSON.stringify(active_list) : null,
|
||||||
|
// active_list,
|
||||||
|
ranges_response,
|
||||||
|
},
|
||||||
|
id
|
||||||
|
);
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Output_variables", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
req.flash("success", "Output variable edited successfully");
|
||||||
|
|
||||||
|
return res.redirect("/admin/output-variables/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Output_variables", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get(
|
||||||
|
"/admin/output-variables-view/:id",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
|
||||||
|
async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const outputVariablesAdminDetailViewModel = require("../../view_models/output_variables_admin_detail_view_model");
|
||||||
|
|
||||||
|
var viewModel = new outputVariablesAdminDetailViewModel(db.output_variable, "Output variable details", "", "", "/admin/output-variables");
|
||||||
|
|
||||||
|
const data = await db.output_variable.getByPK(id);
|
||||||
|
|
||||||
|
if (data.active_list) {
|
||||||
|
const actives = await db.active.findAll({
|
||||||
|
where: {
|
||||||
|
id: JSON.parse(data.active_list),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
data.active_list = actives.map((active) => {
|
||||||
|
return { name: active.name, id: active.id };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Output variable not found";
|
||||||
|
viewModel.detail_fields = { ...viewModel.detail_fields, id: "N/A", name: "N/A", active_list: "N/A", ranges_response: "N/A" };
|
||||||
|
} else {
|
||||||
|
viewModel.detail_fields = {
|
||||||
|
...viewModel.detail_fields,
|
||||||
|
id: data["id"] || "N/A",
|
||||||
|
name: data["name"] || "N/A",
|
||||||
|
active_list: data["active_list"] || "N/A",
|
||||||
|
ranges_response: data["ranges_response"] || "N/A",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
res.render("admin/View_Output_variables", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
viewModel.detail_fields = { ...viewModel.detail_fields, id: "N/A", name: "N/A", active_list: "N/A", ranges_response: "N/A" };
|
||||||
|
res.render("admin/View_Output_variables", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get("/admin/output-variables-delete/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const outputVariablesAdminDeleteViewModel = require("../../view_models/output_variables_admin_delete_view_model");
|
||||||
|
|
||||||
|
const viewModel = new outputVariablesAdminDeleteViewModel(db.output_variable);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = await db.output_variable.getByPK(id);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
req.flash("error", "Output variable not found");
|
||||||
|
return res.redirect("/admin/output-variables/0");
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
await db.output_variable.realDelete(id);
|
||||||
|
|
||||||
|
req.flash("success", "Output variable was deleted successfully");
|
||||||
|
|
||||||
|
return res.redirect("/admin/output-variables/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
req.flash("error", error.message || "Something went wrong");
|
||||||
|
return res.redirect("/admin/output-variables/0");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
@@ -0,0 +1,624 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const app = require("express").Router();
|
||||||
|
const Sequelize = require("sequelize");
|
||||||
|
const logger = require("../../services/LoggingService");
|
||||||
|
let pagination = require("../../services/PaginationService");
|
||||||
|
let SessionService = require("../../services/SessionService");
|
||||||
|
let JwtService = require("../../services/JwtService");
|
||||||
|
const ValidationService = require("../../services/ValidationService");
|
||||||
|
const PermissionService = require("../../services/PermissionService");
|
||||||
|
const UploadService = require("../../services/UploadService");
|
||||||
|
const AuthService = require("../../services/AuthService");
|
||||||
|
const db = require("../../models");
|
||||||
|
const helpers = require("../../core/helpers");
|
||||||
|
|
||||||
|
const role = 1;
|
||||||
|
|
||||||
|
app.get("/admin/questions/:num", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
let session = req.session;
|
||||||
|
let paginateListViewModel = require("../../view_models/questions_admin_list_paginate_view_model");
|
||||||
|
|
||||||
|
var viewModel = new paginateListViewModel(db.question, "Questiones", session.success, session.error, "/admin/questions");
|
||||||
|
|
||||||
|
const format = req.query.format ? req.query.format : "view";
|
||||||
|
const direction = req.query.direction ? req.query.direction : "ASC";
|
||||||
|
const per_page = req.query.per_page ? req.query.per_page : 10;
|
||||||
|
// req.query.order_by ? req.query.order_by :
|
||||||
|
let order_by = [
|
||||||
|
["quiz_id", direction],
|
||||||
|
["order", direction],
|
||||||
|
];
|
||||||
|
// Check for flash messages
|
||||||
|
const flashMessageSuccess = req.flash("success");
|
||||||
|
if (flashMessageSuccess && flashMessageSuccess.length > 0) {
|
||||||
|
viewModel.success = flashMessageSuccess[0];
|
||||||
|
}
|
||||||
|
const flashMessageError = req.flash("error");
|
||||||
|
if (flashMessageError && flashMessageError.length > 0) {
|
||||||
|
viewModel.error = flashMessageError[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.set_id(req.query.id ? req.query.id : "");
|
||||||
|
viewModel.set_quiz_id(req.query.quiz_id ? req.query.quiz_id : "");
|
||||||
|
viewModel.set_type(req.query.type ? req.query.type : "");
|
||||||
|
|
||||||
|
let where = helpers.filterEmptyFields({
|
||||||
|
id: viewModel.get_id(),
|
||||||
|
quiz_id: viewModel.get_quiz_id(),
|
||||||
|
type: viewModel.get_type(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const count = await db.question._count(where, [
|
||||||
|
{ model: db.quiz, as: "quiz", required: true },
|
||||||
|
{ model: db.answer, as: "answers", required: false },
|
||||||
|
]);
|
||||||
|
|
||||||
|
viewModel.set_total_rows(count);
|
||||||
|
viewModel.set_per_page(+per_page);
|
||||||
|
viewModel.set_page(+req.params.num);
|
||||||
|
viewModel.set_query(req.query);
|
||||||
|
viewModel.set_sort_base_url(`/admin/questions/${+req.params.num}`);
|
||||||
|
viewModel.set_sort(direction);
|
||||||
|
|
||||||
|
const list = await db.question.getPaginatedV2(viewModel.get_page() - 1 < 0 ? 0 : viewModel.get_page(), viewModel.get_per_page(), where, order_by, direction, [
|
||||||
|
{ model: db.quiz, as: "quiz", required: true },
|
||||||
|
{ model: db.answer, as: "answers", required: false },
|
||||||
|
]);
|
||||||
|
|
||||||
|
viewModel.set_list(list);
|
||||||
|
|
||||||
|
viewModel.quiz = await db.quiz;
|
||||||
|
|
||||||
|
if (format == "csv") {
|
||||||
|
const csv = viewModel.to_csv();
|
||||||
|
return res
|
||||||
|
.set({
|
||||||
|
"Content-Type": "text/csv",
|
||||||
|
"Content-Disposition": 'attachment; filename="export.csv"',
|
||||||
|
})
|
||||||
|
.send(csv);
|
||||||
|
}
|
||||||
|
return res.render("admin/Questions", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Questions", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/admin/questions-add", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
const questionsAdminAddViewModel = require("../../view_models/questions_admin_add_view_model");
|
||||||
|
|
||||||
|
const viewModel = new questionsAdminAddViewModel(db.question, "Add question", "", "", "/admin/questions");
|
||||||
|
viewModel.quizzes = await db.quiz.getAll();
|
||||||
|
for (const quiz of viewModel.quizzes) {
|
||||||
|
const question = await db.question.findAll({
|
||||||
|
where: {
|
||||||
|
quiz_id: quiz.id,
|
||||||
|
},
|
||||||
|
limit: 1,
|
||||||
|
order: [["order", "DESC"]],
|
||||||
|
});
|
||||||
|
quiz.lastOrder = question[0].order;
|
||||||
|
}
|
||||||
|
viewModel.questions = await db.question.getAll();
|
||||||
|
viewModel.outputVariables = await db.output_variable.getAll();
|
||||||
|
res.render("admin/Add_Questions", viewModel);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post(
|
||||||
|
"/admin/questions-add",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
ValidationService.validateInput(
|
||||||
|
{ quiz_id: "required", question: "required", type: "required", order: "required" },
|
||||||
|
{
|
||||||
|
"quiz_id.required": "QuizId is required",
|
||||||
|
"question.required": "Question is required",
|
||||||
|
"type.required": "Type is required",
|
||||||
|
"order.required": "Order is required",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
async function (req, res, next) {
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
const questionsAdminAddViewModel = require("../../view_models/questions_admin_add_view_model");
|
||||||
|
|
||||||
|
const viewModel = new questionsAdminAddViewModel(db.question, "Add question", "", "", "/admin/questions");
|
||||||
|
viewModel.quizzes = await db.quiz.getAll();
|
||||||
|
viewModel.questions = await db.question.getAll();
|
||||||
|
viewModel.outputVariables = await db.output_variable.getAll();
|
||||||
|
|
||||||
|
// TODO use separate controller for image upload
|
||||||
|
// {{{upload_field_setter}}}
|
||||||
|
|
||||||
|
const { quiz_id, question, order, image_width, image_height, note, note_type, depends_on, slider_range, output_variable_name, weight, extra_output_variable, type } = req.body;
|
||||||
|
|
||||||
|
viewModel.form_fields = {
|
||||||
|
...viewModel.form_fields,
|
||||||
|
quiz_id,
|
||||||
|
question,
|
||||||
|
order,
|
||||||
|
note,
|
||||||
|
image_width,
|
||||||
|
image_height,
|
||||||
|
note_type,
|
||||||
|
depends_on,
|
||||||
|
slider_range,
|
||||||
|
output_variable_name,
|
||||||
|
weight,
|
||||||
|
extra_output_variable,
|
||||||
|
type,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
viewModel.error = req.validationError;
|
||||||
|
return res.render("admin/Add_Questions", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
const data = await db.question.insert({
|
||||||
|
quiz_id,
|
||||||
|
question,
|
||||||
|
order,
|
||||||
|
image_width: image_width ? image_width : null,
|
||||||
|
image_height: image_height ? image_height : null,
|
||||||
|
note: note ? note : null,
|
||||||
|
note_type: note_type ? note_type : null,
|
||||||
|
depends_on: depends_on ? depends_on : null,
|
||||||
|
slider_range: slider_range ? slider_range : null,
|
||||||
|
output_variable_name: output_variable_name ? output_variable_name : null,
|
||||||
|
weight: weight ? weight : null,
|
||||||
|
extra_output_variable: extra_output_variable ? extra_output_variable : null,
|
||||||
|
type,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Add_Questions", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
req.flash("success", "Question created successfully");
|
||||||
|
return res.redirect("/admin/questions/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Add_Questions", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get("/admin/questions-edit/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
const questionsAdminEditViewModel = require("../../view_models/questions_admin_edit_view_model");
|
||||||
|
|
||||||
|
const viewModel = new questionsAdminEditViewModel(db.question, "Edit question", "", "", "/admin/questions");
|
||||||
|
const flashMessageSuccess = req.flash("success");
|
||||||
|
if (flashMessageSuccess && flashMessageSuccess.length > 0) {
|
||||||
|
viewModel.success = flashMessageSuccess[0];
|
||||||
|
}
|
||||||
|
const flashMessageError = req.flash("error");
|
||||||
|
if (flashMessageError && flashMessageError.length > 0) {
|
||||||
|
viewModel.error = flashMessageError[0];
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const exists = await db.question.findOne({
|
||||||
|
where: { id },
|
||||||
|
order: [["answers", "order", "ASC"]],
|
||||||
|
include: [{ model: db.answer, as: "answers", include: [{ model: db.image, as: "image" }] }],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
req.flash("error", "Question not found");
|
||||||
|
return res.redirect("/admin/questions/0");
|
||||||
|
}
|
||||||
|
const values = exists;
|
||||||
|
Object.keys(viewModel.form_fields).forEach((field) => {
|
||||||
|
viewModel.form_fields[field] = values[field] || "";
|
||||||
|
});
|
||||||
|
viewModel.question = exists;
|
||||||
|
viewModel.quiz = db.quiz;
|
||||||
|
viewModel.quizzes = await db.quiz.getAll();
|
||||||
|
viewModel.questions = await db.question.getAll();
|
||||||
|
viewModel.outputVariables = await db.output_variable.getAll();
|
||||||
|
viewModel.actives = await db.active.getAll();
|
||||||
|
viewModel.nextQuestionId;
|
||||||
|
let lastQuestionId = await db.question.findAll({ order_by: ["id", "DESC"] }).then((data) => data[0].id);
|
||||||
|
let found = false;
|
||||||
|
let nextId = parseInt(exists.id) + 1;
|
||||||
|
while (!found) {
|
||||||
|
const nextQuestion = await db.question.getByPK(nextId);
|
||||||
|
if (nextQuestion) {
|
||||||
|
viewModel.nextQuestionId = nextQuestion.id;
|
||||||
|
found = true;
|
||||||
|
} else {
|
||||||
|
if (nextId >= lastQuestionId) break;
|
||||||
|
}
|
||||||
|
nextId++;
|
||||||
|
}
|
||||||
|
//remaining actives unselected
|
||||||
|
if (exists.answers && exists.answers?.length > 0) {
|
||||||
|
viewModel.lastOrderCount = exists.answers[exists.answers.length - 1].order;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.render("admin/Edit_Questions", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Questions", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
app.get("/admin/answers/refill/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const actives = await db.active.getAll();
|
||||||
|
await db.answer.destroy({ where: { question_id: id } });
|
||||||
|
|
||||||
|
await db.answer.insert({
|
||||||
|
question_id: id,
|
||||||
|
order: 1,
|
||||||
|
answer: "Banana",
|
||||||
|
});
|
||||||
|
await db.answer.insert({
|
||||||
|
question_id: id,
|
||||||
|
order: 2,
|
||||||
|
answer: "Olive",
|
||||||
|
});
|
||||||
|
await db.answer.insert({
|
||||||
|
question_id: id,
|
||||||
|
order: 3,
|
||||||
|
answer: "Sunflowers",
|
||||||
|
});
|
||||||
|
|
||||||
|
let order = 3;
|
||||||
|
for (const active of actives) {
|
||||||
|
if (active.name !== "Blank") {
|
||||||
|
await db.answer.insert({
|
||||||
|
question_id: id,
|
||||||
|
order: order + 1,
|
||||||
|
answer: active.name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
order++;
|
||||||
|
}
|
||||||
|
req.flash("success", "Answers refilled successfully");
|
||||||
|
return res.redirect("/admin/questions-edit/" + id);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
req.flash("error", error.message || "Something went wrong");
|
||||||
|
return res.redirect("/admin/questions-edit/" + id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post(
|
||||||
|
"/admin/questions-edit/:id",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
ValidationService.validateInput(
|
||||||
|
{ quiz_id: "required", question: "required", type: "required", question_order: "required" },
|
||||||
|
{
|
||||||
|
"quiz_id.required": "QuizId is required",
|
||||||
|
"question.required": "Question is required",
|
||||||
|
"type.required": "Type is required",
|
||||||
|
"question_order.required": "Order is required",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
const questionsAdminEditViewModel = require("../../view_models/questions_admin_edit_view_model");
|
||||||
|
|
||||||
|
const viewModel = new questionsAdminEditViewModel(db.question, "Edit question", "", "", "/admin/questions");
|
||||||
|
viewModel.quizzes = await db.quiz.getAll();
|
||||||
|
viewModel.questions = await db.question.getAll();
|
||||||
|
viewModel.outputVariables = await db.output_variable.getAll();
|
||||||
|
viewModel.nextQuestionId;
|
||||||
|
let lastQuestionId = await db.question.findAll({ order_by: ["id", "DESC"] }).then((data) => data[0].id);
|
||||||
|
let found = false;
|
||||||
|
let nextId = parseInt(id) + 1;
|
||||||
|
while (!found) {
|
||||||
|
const nextQuestion = await db.question.getByPK(nextId);
|
||||||
|
if (nextQuestion) {
|
||||||
|
viewModel.nextQuestionId = nextQuestion.id;
|
||||||
|
found = true;
|
||||||
|
} else {
|
||||||
|
if (nextId >= lastQuestionId) break;
|
||||||
|
}
|
||||||
|
nextId++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { quiz_id, question, question_order, note, image_width, image_height, note_type, depends_on, slider_range, output_variable_name, weight, extra_output_variable, type } = req.body;
|
||||||
|
const { ids, answer, answer_value, hide_answer, explaination, image_id, response_header, response_body } = req.body;
|
||||||
|
|
||||||
|
viewModel.form_fields = {
|
||||||
|
...viewModel.form_fields,
|
||||||
|
quiz_id,
|
||||||
|
question,
|
||||||
|
order: question_order,
|
||||||
|
note,
|
||||||
|
image_width,
|
||||||
|
image_height,
|
||||||
|
note_type,
|
||||||
|
depends_on,
|
||||||
|
slider_range,
|
||||||
|
output_variable_name,
|
||||||
|
weight,
|
||||||
|
extra_output_variable,
|
||||||
|
type,
|
||||||
|
};
|
||||||
|
|
||||||
|
delete viewModel.form_fields.id;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
console.error(error);
|
||||||
|
req.flash("error", req.validationError);
|
||||||
|
return res.redirect(`/admin/questions-edit/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const resourceExists = await db.question.getByPK(id);
|
||||||
|
if (!resourceExists) {
|
||||||
|
req.flash("error", "Question not found");
|
||||||
|
return res.redirect(`/admin/questions-edit/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
await db.question.edit(
|
||||||
|
{
|
||||||
|
quiz_id,
|
||||||
|
question,
|
||||||
|
question_order,
|
||||||
|
type,
|
||||||
|
image_width: image_width ? image_width : null,
|
||||||
|
image_height: image_height ? image_height : null,
|
||||||
|
note: note ? note : null,
|
||||||
|
note_type: note_type ? note_type : null,
|
||||||
|
depends_on: depends_on ? depends_on : null,
|
||||||
|
slider_range: slider_range ? slider_range : null,
|
||||||
|
output_variable_name: output_variable_name ? output_variable_name : null,
|
||||||
|
weight: weight ? weight : null,
|
||||||
|
extra_output_variable: extra_output_variable ? extra_output_variable : null,
|
||||||
|
},
|
||||||
|
id
|
||||||
|
);
|
||||||
|
if (Array.isArray(ids) && ids.length) {
|
||||||
|
for (let i = 0; i < ids.length; i++) {
|
||||||
|
await db.answer.edit(
|
||||||
|
{
|
||||||
|
answer: answer[i] ? answer[i] : null,
|
||||||
|
answer_value: answer_value[i] ? answer_value[i] : null,
|
||||||
|
hide_answer: hide_answer[i] ? hide_answer[i] : null,
|
||||||
|
order: i + 1,
|
||||||
|
explaination: explaination[i] ? explaination[i] : null,
|
||||||
|
image_id: image_id[i] ? image_id[i] : null,
|
||||||
|
response_header: response_header[i] ? response_header[i] : null,
|
||||||
|
response_body: response_body[i] ? response_body[i] : null,
|
||||||
|
black_list_actives: req.body[`black_list_actives_${ids[i]}`]
|
||||||
|
? !Array.isArray(req.body[`black_list_actives_${ids[i]}`])
|
||||||
|
? JSON.stringify([req.body[`black_list_actives_${ids[i]}`]])
|
||||||
|
: JSON.stringify(req.body[`black_list_actives_${ids[i]}`])
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
ids[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (!Array.isArray(ids) && ids) {
|
||||||
|
await db.answer.edit(
|
||||||
|
{
|
||||||
|
answer: answer ? answer : null,
|
||||||
|
answer_value: answer_value ? answer_value : null,
|
||||||
|
hide_answer: hide_answer ? hide_answer : null,
|
||||||
|
order: 1,
|
||||||
|
explaination: explaination ? explaination : null,
|
||||||
|
image_id: image_id ? image_id : null,
|
||||||
|
response_header: response_header ? response_header : null,
|
||||||
|
response_body: response_body ? response_body : null,
|
||||||
|
black_list_actives: req.body[`black_list_actives_${ids}`]
|
||||||
|
? !Array.isArray(req.body[`black_list_actives_${ids}`])
|
||||||
|
? JSON.stringify([req.body[`black_list_actives_${ids}`]])
|
||||||
|
: JSON.stringify(req.body[`black_list_actives_${ids}`])
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
ids
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
req.flash("success", "Question edited successfully");
|
||||||
|
return res.redirect(`/admin/questions-edit/${id}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
req.flash("error", error.message || "Something went wrong");
|
||||||
|
return res.redirect(`/admin/questions-edit/${id}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get(
|
||||||
|
"/admin/questions-view/:id",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
|
||||||
|
async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const questionsAdminDetailViewModel = require("../../view_models/questions_admin_detail_view_model");
|
||||||
|
|
||||||
|
var viewModel = new questionsAdminDetailViewModel(db.question, "Question details", "", "", "/admin/questions");
|
||||||
|
|
||||||
|
const data = await db.question.get_question_quiz(id, db);
|
||||||
|
data.type = db.question.type_mapping()[data.type];
|
||||||
|
data.target = db.question.target_mapping()[data.target];
|
||||||
|
data.note_type = db.question.note_type_mapping()[data.note_type];
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Question not found";
|
||||||
|
viewModel.detail_fields = {
|
||||||
|
...viewModel.detail_fields,
|
||||||
|
id: "N/A",
|
||||||
|
"quiz.name": "N/A",
|
||||||
|
question: "N/A",
|
||||||
|
question_arguments: "N/A",
|
||||||
|
order: "N/A",
|
||||||
|
note: "N/A",
|
||||||
|
note_type: "N/A",
|
||||||
|
target: "N/A",
|
||||||
|
response: "N/A",
|
||||||
|
save_response_into: "N/A",
|
||||||
|
depends_on: "N/A",
|
||||||
|
slider_range: "N/A",
|
||||||
|
output_variable_name: "N/A",
|
||||||
|
weight: "N/A",
|
||||||
|
extra_output_variable: "N/A",
|
||||||
|
type: "N/A",
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
viewModel.detail_fields = {
|
||||||
|
...viewModel.detail_fields,
|
||||||
|
id: data["id"] || "N/A",
|
||||||
|
"quiz.name": data["quiz"]["name"] || "N/A",
|
||||||
|
question: data["question"] || "N/A",
|
||||||
|
question_arguments: data["question_arguments"] || "N/A",
|
||||||
|
order: data["order"] || "N/A",
|
||||||
|
note: data["note"] || "N/A",
|
||||||
|
note_type: data["note_type"] || "N/A",
|
||||||
|
target: data["target"] || "N/A",
|
||||||
|
response: data["response"] || "N/A",
|
||||||
|
save_response_into: data["save_response_into"] || "N/A",
|
||||||
|
depends_on: data["depends_on"] || "N/A",
|
||||||
|
slider_range: data["slider_range"] || "N/A",
|
||||||
|
output_variable_name: data["output_variable_name"] || "N/A",
|
||||||
|
weight: data["weight"] || "N/A",
|
||||||
|
extra_output_variable: data["extra_output_variable"] || "N/A",
|
||||||
|
type: data["type"] || "N/A",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
res.render("admin/View_Questions", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
viewModel.detail_fields = {
|
||||||
|
...viewModel.detail_fields,
|
||||||
|
id: "N/A",
|
||||||
|
"quiz.name": "N/A",
|
||||||
|
question: "N/A",
|
||||||
|
question_arguments: "N/A",
|
||||||
|
order: "N/A",
|
||||||
|
note: "N/A",
|
||||||
|
note_type: "N/A",
|
||||||
|
target: "N/A",
|
||||||
|
response: "N/A",
|
||||||
|
save_response_into: "N/A",
|
||||||
|
depends_on: "N/A",
|
||||||
|
slider_range: "N/A",
|
||||||
|
output_variable_name: "N/A",
|
||||||
|
weight: "N/A",
|
||||||
|
extra_output_variable: "N/A",
|
||||||
|
type: "N/A",
|
||||||
|
};
|
||||||
|
res.render("admin/View_Questions", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get("/admin/questions-delete/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const questionsAdminDeleteViewModel = require("../../view_models/questions_admin_delete_view_model");
|
||||||
|
|
||||||
|
const viewModel = new questionsAdminDeleteViewModel(db.question);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = await db.question.getByPK(id);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
req.flash("error", "Question not found");
|
||||||
|
return res.redirect("/admin/questions/0");
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
await db.question.realDelete(id);
|
||||||
|
await db.answer.destroy({
|
||||||
|
where: { question_id: id },
|
||||||
|
});
|
||||||
|
req.flash("success", "Question was deleted successfully");
|
||||||
|
|
||||||
|
return res.redirect("/admin/questions/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
req.flash("error", error.message || "Something went wrong");
|
||||||
|
return res.redirect("/admin/questions/0");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// APIS
|
||||||
|
|
||||||
|
app.get("/admin/api/questions", async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
const session = req.session;
|
||||||
|
let listViewModel = require("../../view_models/questions_admin_list_paginate_view_model");
|
||||||
|
let viewModel = new listViewModel(db.question, "Questiones", session.success, session.error, "/admin/questions");
|
||||||
|
const direction = req.query.direction ? req.query.direction : "ASC";
|
||||||
|
const page = req.query.page ? parseInt(req.query.page) : 1;
|
||||||
|
const limit = req.query.limit ? parseInt(req.query.limit) : 10;
|
||||||
|
const offset = (page - 1) * limit;
|
||||||
|
let order_by = req.query.order_by ? req.query.order_by : viewModel.get_field_column()[0];
|
||||||
|
let orderAssociations = [];
|
||||||
|
viewModel.set_order_by(order_by);
|
||||||
|
let joins = order_by.includes(".") ? order_by.split(".") : [];
|
||||||
|
order_by = order_by.includes(".") ? joins[joins.length - 1] : order_by;
|
||||||
|
if (joins.length > 0) {
|
||||||
|
for (let i = joins.length - 1; i > 0; i--) {
|
||||||
|
orderAssociations.push(`${joins[i - 1]}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
viewModel.set_id(req.query.id ? req.query.id : "");
|
||||||
|
viewModel.set_quiz_id(req.query.quiz_id ? req.query.quiz_id : "");
|
||||||
|
viewModel.set_type(req.query.type ? req.query.type : "");
|
||||||
|
|
||||||
|
let where = helpers.filterEmptyFields({
|
||||||
|
id: viewModel.get_id(),
|
||||||
|
quiz_id: viewModel.get_quiz_id(),
|
||||||
|
type: viewModel.get_type(),
|
||||||
|
});
|
||||||
|
const { rows: allItems, count } = await db.question.findAndCountAll({
|
||||||
|
where: where,
|
||||||
|
limit: limit == 0 ? null : limit,
|
||||||
|
offset: offset,
|
||||||
|
include: { all: true, nested: true },
|
||||||
|
order: [["id", direction]],
|
||||||
|
distinct: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = {
|
||||||
|
items: allItems,
|
||||||
|
page,
|
||||||
|
nextPage: limit == 0 ? false : count > offset + limit ? page + 1 : false,
|
||||||
|
retrievedCount: allItems.length,
|
||||||
|
fullCount: count,
|
||||||
|
};
|
||||||
|
|
||||||
|
return res.status(201).json({ success: true, data: response });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return res.status(500).json({ success: false, message: error.message || "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
module.exports = app;
|
||||||
@@ -0,0 +1,460 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const app = require("express").Router();
|
||||||
|
const Sequelize = require("sequelize");
|
||||||
|
const logger = require("../../services/LoggingService");
|
||||||
|
let pagination = require("../../services/PaginationService");
|
||||||
|
let SessionService = require("../../services/SessionService");
|
||||||
|
let JwtService = require("../../services/JwtService");
|
||||||
|
const ValidationService = require("../../services/ValidationService");
|
||||||
|
const PermissionService = require("../../services/PermissionService");
|
||||||
|
const UploadService = require("../../services/UploadService");
|
||||||
|
const AuthService = require("../../services/AuthService");
|
||||||
|
const db = require("../../models");
|
||||||
|
const helpers = require("../../core/helpers");
|
||||||
|
|
||||||
|
const role = 1;
|
||||||
|
|
||||||
|
app.get("/admin/quizzes/:num", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
let session = req.session;
|
||||||
|
let paginateListViewModel = require("../../view_models/quizzes_admin_list_paginate_view_model");
|
||||||
|
|
||||||
|
var viewModel = new paginateListViewModel(db.quiz, "Quizzes", session.success, session.error, "/admin/quizzes");
|
||||||
|
|
||||||
|
const format = req.query.format ? req.query.format : "view";
|
||||||
|
const direction = req.query.direction ? req.query.direction : "ASC";
|
||||||
|
const per_page = req.query.per_page ? req.query.per_page : 10;
|
||||||
|
let order_by = req.query.order_by ? req.query.order_by : viewModel.get_field_column()[0];
|
||||||
|
let orderAssociations = [];
|
||||||
|
viewModel.set_order_by(order_by);
|
||||||
|
let joins = order_by.includes(".") ? order_by.split(".") : [];
|
||||||
|
order_by = order_by.includes(".") ? joins[joins.length - 1] : order_by;
|
||||||
|
if (joins.length > 0) {
|
||||||
|
for (let i = joins.length - 1; i > 0; i--) {
|
||||||
|
orderAssociations.push(`${joins[i - 1]}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check for flash messages
|
||||||
|
const flashMessageSuccess = req.flash("success");
|
||||||
|
if (flashMessageSuccess && flashMessageSuccess.length > 0) {
|
||||||
|
viewModel.success = flashMessageSuccess[0];
|
||||||
|
}
|
||||||
|
const flashMessageError = req.flash("error");
|
||||||
|
if (flashMessageError && flashMessageError.length > 0) {
|
||||||
|
viewModel.error = flashMessageError[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.set_id(req.query.id ? req.query.id : "");
|
||||||
|
viewModel.set_name(req.query.name ? req.query.name : "");
|
||||||
|
|
||||||
|
let where = helpers.filterEmptyFields({
|
||||||
|
id: viewModel.get_id(),
|
||||||
|
name: viewModel.get_name(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let associatedWhere = helpers.filterEmptyFields({});
|
||||||
|
const isAssociationRequired = Object.keys(associatedWhere).length > 0 ? true : false;
|
||||||
|
|
||||||
|
const count = await db.quiz._count(where, [{ model: db.question, where: associatedWhere, required: isAssociationRequired, as: "questions" }]);
|
||||||
|
|
||||||
|
viewModel.set_total_rows(count);
|
||||||
|
viewModel.set_per_page(+per_page);
|
||||||
|
viewModel.set_page(+req.params.num);
|
||||||
|
viewModel.set_query(req.query);
|
||||||
|
viewModel.set_sort_base_url(`/admin/quizzes/${+req.params.num}`);
|
||||||
|
viewModel.set_sort(direction);
|
||||||
|
|
||||||
|
const list = await db.quiz.get_question_paginated(
|
||||||
|
db,
|
||||||
|
associatedWhere,
|
||||||
|
viewModel.get_page() - 1 < 0 ? 0 : viewModel.get_page(),
|
||||||
|
viewModel.get_per_page(),
|
||||||
|
where,
|
||||||
|
order_by,
|
||||||
|
direction,
|
||||||
|
orderAssociations
|
||||||
|
);
|
||||||
|
|
||||||
|
viewModel.set_list(list);
|
||||||
|
|
||||||
|
viewModel.question = await db.question;
|
||||||
|
|
||||||
|
if (format == "csv") {
|
||||||
|
const csv = viewModel.to_csv();
|
||||||
|
return res
|
||||||
|
.set({
|
||||||
|
"Content-Type": "text/csv",
|
||||||
|
"Content-Disposition": 'attachment; filename="export.csv"',
|
||||||
|
})
|
||||||
|
.send(csv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (format != 'view') {
|
||||||
|
// res.json(viewModel.to_json());
|
||||||
|
// } else {
|
||||||
|
// }
|
||||||
|
|
||||||
|
return res.render("admin/Quizzes", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Quizzes", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/admin/quizzes-add", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
const quizzesAdminAddViewModel = require("../../view_models/quizzes_admin_add_view_model");
|
||||||
|
|
||||||
|
const viewModel = new quizzesAdminAddViewModel(db.quiz, "Add quiz", "", "", "/admin/quizzes");
|
||||||
|
|
||||||
|
res.render("admin/Add_Quizzes", viewModel);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post(
|
||||||
|
"/admin/quizzes-add",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
ValidationService.validateInput({ name: "required" }, { "name.required": "Name is required" }),
|
||||||
|
async function (req, res, next) {
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
const quizzesAdminAddViewModel = require("../../view_models/quizzes_admin_add_view_model");
|
||||||
|
|
||||||
|
const viewModel = new quizzesAdminAddViewModel(db.quiz, "Add quiz", "", "", "/admin/quizzes");
|
||||||
|
|
||||||
|
// TODO use separate controller for image upload
|
||||||
|
// {{{upload_field_setter}}}
|
||||||
|
|
||||||
|
const { name, description } = req.body;
|
||||||
|
|
||||||
|
viewModel.form_fields = {
|
||||||
|
...viewModel.form_fields,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
viewModel.error = req.validationError;
|
||||||
|
return res.render("admin/Add_Quizzes", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
const data = await db.quiz.insert({ name, description });
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Add_Quizzes", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.activity_log.insert({
|
||||||
|
action: "ADD",
|
||||||
|
name: "Admin_quiz_controller.js",
|
||||||
|
portal: "admin",
|
||||||
|
data: JSON.stringify({ name, description }),
|
||||||
|
});
|
||||||
|
|
||||||
|
req.flash("success", "Quiz created successfully");
|
||||||
|
return res.redirect("/admin/quizzes/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Add_Quizzes", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get("/admin/quizzes-edit/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
const quizzesAdminEditViewModel = require("../../view_models/quizzes_admin_edit_view_model");
|
||||||
|
|
||||||
|
const viewModel = new quizzesAdminEditViewModel(db.quiz, "Edit quiz", "", "", "/admin/quizzes");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = await db.quiz.getByPK(id);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
req.flash("error", "Quiz not found");
|
||||||
|
return res.redirect("/admin/quizzes/0");
|
||||||
|
}
|
||||||
|
const values = exists;
|
||||||
|
Object.keys(viewModel.form_fields).forEach((field) => {
|
||||||
|
viewModel.form_fields[field] = values[field] || "";
|
||||||
|
});
|
||||||
|
viewModel.question = db.question;
|
||||||
|
return res.render("admin/Edit_Quizzes", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Quizzes", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post(
|
||||||
|
"/admin/quizzes-edit/:id",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
ValidationService.validateInput({ name: "required" }, { "name.required": "Name is required" }),
|
||||||
|
async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
const quizzesAdminEditViewModel = require("../../view_models/quizzes_admin_edit_view_model");
|
||||||
|
|
||||||
|
const viewModel = new quizzesAdminEditViewModel(db.quiz, "Edit quiz", "", "", "/admin/quizzes");
|
||||||
|
|
||||||
|
const { name, description } = req.body;
|
||||||
|
|
||||||
|
viewModel.form_fields = {
|
||||||
|
...viewModel.form_fields,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
};
|
||||||
|
|
||||||
|
delete viewModel.form_fields.id;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
viewModel.error = req.validationError;
|
||||||
|
return res.render("admin/Edit_Quizzes", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
const resourceExists = await db.quiz.getByPK(id);
|
||||||
|
if (!resourceExists) {
|
||||||
|
req.flash("error", "Quiz not found");
|
||||||
|
return res.redirect("/admin/quizzes/0");
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
let data = await db.quiz.edit({ name, description }, id);
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Quizzes", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resourceExists.questions) {
|
||||||
|
if (resourceExists.questions.length == 1) {
|
||||||
|
resourceExists.questions.forEach(async (item) => {
|
||||||
|
data = await db.question.edit(helpers.filterEmptyFields({}), item.id);
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Quizzes", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
resourceExists.questions.forEach(async (item, index) => {
|
||||||
|
data = await db.question.edit(helpers.filterEmptyFields({}), item.id);
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Quizzes", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.activity_log.insert({
|
||||||
|
action: "EDIT",
|
||||||
|
name: "Admin_quiz_controller.js",
|
||||||
|
portal: "admin",
|
||||||
|
data: JSON.stringify({ name, description }),
|
||||||
|
});
|
||||||
|
|
||||||
|
req.flash("success", "Quiz edited successfully");
|
||||||
|
|
||||||
|
return res.redirect("/admin/quizzes/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Quizzes", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get(
|
||||||
|
"/admin/quizzes-view/:id",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
|
||||||
|
async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const quizzesAdminDetailViewModel = require("../../view_models/quizzes_admin_detail_view_model");
|
||||||
|
|
||||||
|
var viewModel = new quizzesAdminDetailViewModel(db.quiz, "Quiz details", "", "", "/admin/quizzes");
|
||||||
|
|
||||||
|
const data = await db.quiz.getByPK(id);
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Quiz not found";
|
||||||
|
viewModel.detail_fields = { ...viewModel.detail_fields, id: "N/A", name: "N/A", description: "N/A" };
|
||||||
|
} else {
|
||||||
|
viewModel.detail_fields = {
|
||||||
|
...viewModel.detail_fields,
|
||||||
|
id: data["id"] || "N/A",
|
||||||
|
name: data["name"] || "N/A",
|
||||||
|
description: data["description"] || "N/A",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
res.render("admin/View_Quizzes", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
viewModel.detail_fields = { ...viewModel.detail_fields, id: "N/A", name: "N/A", description: "N/A" };
|
||||||
|
res.render("admin/View_Quizzes", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get("/admin/quizzes-delete/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const quizzesAdminDeleteViewModel = require("../../view_models/quizzes_admin_delete_view_model");
|
||||||
|
|
||||||
|
const viewModel = new quizzesAdminDeleteViewModel(db.quiz);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = await db.quiz.getByPK(id);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
req.flash("error", "Quiz not found");
|
||||||
|
return res.redirect("/admin/quizzes/0");
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
await db.quiz.realDelete(id);
|
||||||
|
await db.question.destroy({
|
||||||
|
where: {
|
||||||
|
quiz_id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await db.activity_log.insert({
|
||||||
|
action: "DELETE",
|
||||||
|
name: "Admin_quiz_controller.js",
|
||||||
|
portal: "admin",
|
||||||
|
data: JSON.stringify(exists),
|
||||||
|
});
|
||||||
|
|
||||||
|
req.flash("success", "Quiz was deleted successfully");
|
||||||
|
|
||||||
|
return res.redirect("/admin/quizzes/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
req.flash("error", error.message || "Something went wrong");
|
||||||
|
return res.redirect("/admin/quizzes/0");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// APIS
|
||||||
|
|
||||||
|
app.get("/admin/api/quizzes", async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
const session = req.session;
|
||||||
|
let listViewModel = require("../../view_models/quizzes_admin_list_paginate_view_model");
|
||||||
|
let viewModel = new listViewModel(db.quiz, "Quizzes", session.success, session.error, "/admin/quizzes");
|
||||||
|
const direction = req.query.direction ? req.query.direction : "ASC";
|
||||||
|
const page = req.query.page ? parseInt(req.query.page) : 1;
|
||||||
|
const limit = req.query.limit ? parseInt(req.query.limit) : 10;
|
||||||
|
const offset = (page - 1) * limit;
|
||||||
|
let order_by = req.query.order_by ? req.query.order_by : viewModel.get_field_column()[0];
|
||||||
|
let orderAssociations = [];
|
||||||
|
viewModel.set_order_by(order_by);
|
||||||
|
let joins = order_by.includes(".") ? order_by.split(".") : [];
|
||||||
|
order_by = order_by.includes(".") ? joins[joins.length - 1] : order_by;
|
||||||
|
if (joins.length > 0) {
|
||||||
|
for (let i = joins.length - 1; i > 0; i--) {
|
||||||
|
orderAssociations.push(`${joins[i - 1]}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.set_id(req.query.id ? req.query.id : "");
|
||||||
|
viewModel.set_name(req.query.name ? req.query.name : "");
|
||||||
|
|
||||||
|
let where = helpers.filterEmptyFields({
|
||||||
|
id: viewModel.get_id(),
|
||||||
|
name: viewModel.get_name(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const { rows: allItems, count } = await db.quiz.findAndCountAll({
|
||||||
|
where: where,
|
||||||
|
limit: limit == 0 ? null : limit,
|
||||||
|
offset: offset,
|
||||||
|
// include: { all: true, nested: true },
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.question,
|
||||||
|
as: "questions",
|
||||||
|
order: [["order", "ASC"]],
|
||||||
|
separate: true,
|
||||||
|
required: false,
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.answer,
|
||||||
|
as: "answers",
|
||||||
|
required: false,
|
||||||
|
separate: true,
|
||||||
|
order: [["order", "ASC"]],
|
||||||
|
include: [{ model: db.image, as: "image", required: false }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
order: [["id", direction]],
|
||||||
|
distinct: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const row of allItems) {
|
||||||
|
if (row.questions) {
|
||||||
|
for (const question of row.questions) {
|
||||||
|
if (question.answers) {
|
||||||
|
for (const answer of question.answers) {
|
||||||
|
if (answer.black_list_actives) {
|
||||||
|
const blActivesListIds = JSON.parse(answer.black_list_actives);
|
||||||
|
const blActivesListNames = await db.active
|
||||||
|
.findAll({
|
||||||
|
where: {
|
||||||
|
id: blActivesListIds,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
return data.map((item) => {
|
||||||
|
item = item.name;
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
answer.black_list_actives = JSON.stringify(blActivesListNames);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const response = {
|
||||||
|
items: allItems,
|
||||||
|
page,
|
||||||
|
nextPage: limit == 0 ? false : count > offset + limit ? page + 1 : false,
|
||||||
|
retrievedCount: allItems.length,
|
||||||
|
fullCount: count,
|
||||||
|
};
|
||||||
|
|
||||||
|
return res.status(201).json({ success: true, data: response });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return res.status(500).json({ success: false, message: error.message || "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
@@ -0,0 +1,476 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const app = require("express").Router();
|
||||||
|
const Sequelize = require("sequelize");
|
||||||
|
const logger = require("../../services/LoggingService");
|
||||||
|
let pagination = require("../../services/PaginationService");
|
||||||
|
let SessionService = require("../../services/SessionService");
|
||||||
|
let JwtService = require("../../services/JwtService");
|
||||||
|
const ValidationService = require("../../services/ValidationService");
|
||||||
|
const PermissionService = require("../../services/PermissionService");
|
||||||
|
const UploadService = require("../../services/UploadService");
|
||||||
|
const AuthService = require("../../services/AuthService");
|
||||||
|
const db = require("../../models");
|
||||||
|
const helpers = require("../../core/helpers");
|
||||||
|
|
||||||
|
const role = 1;
|
||||||
|
|
||||||
|
app.get("/admin/profile-sections/:num", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
let session = req.session;
|
||||||
|
let paginateListViewModel = require("../../view_models/result_profile_admin_list_paginate_view_model");
|
||||||
|
|
||||||
|
var viewModel = new paginateListViewModel(db.result_profile, "Profile sections", session.success, session.error, "/admin/profile-sections");
|
||||||
|
|
||||||
|
const format = req.query.format ? req.query.format : "view";
|
||||||
|
const direction = req.query.direction ? req.query.direction : "ASC";
|
||||||
|
const per_page = req.query.per_page ? req.query.per_page : 10;
|
||||||
|
let order_by = req.query.order_by ? req.query.order_by : viewModel.get_field_column()[0];
|
||||||
|
let orderAssociations = [];
|
||||||
|
viewModel.set_order_by(order_by);
|
||||||
|
let joins = order_by.includes(".") ? order_by.split(".") : [];
|
||||||
|
order_by = order_by.includes(".") ? joins[joins.length - 1] : order_by;
|
||||||
|
if (joins.length > 0) {
|
||||||
|
for (let i = joins.length - 1; i > 0; i--) {
|
||||||
|
orderAssociations.push(`${joins[i - 1]}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check for flash messages
|
||||||
|
const flashMessageSuccess = req.flash("success");
|
||||||
|
if (flashMessageSuccess && flashMessageSuccess.length > 0) {
|
||||||
|
viewModel.success = flashMessageSuccess[0];
|
||||||
|
}
|
||||||
|
const flashMessageError = req.flash("error");
|
||||||
|
if (flashMessageError && flashMessageError.length > 0) {
|
||||||
|
viewModel.error = flashMessageError[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.set_id(req.query.id ? req.query.id : "");
|
||||||
|
viewModel.set_section_title(req.query.section_title ? req.query.section_title : "");
|
||||||
|
|
||||||
|
let where = helpers.filterEmptyFields({
|
||||||
|
id: viewModel.get_id(),
|
||||||
|
section_title: viewModel.get_section_title(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const count = await db.result_profile._count(where, []);
|
||||||
|
|
||||||
|
viewModel.set_total_rows(count);
|
||||||
|
viewModel.set_per_page(+per_page);
|
||||||
|
viewModel.set_page(+req.params.num);
|
||||||
|
viewModel.set_query(req.query);
|
||||||
|
viewModel.set_sort_base_url(`/admin/profile-sections/${+req.params.num}`);
|
||||||
|
viewModel.set_sort(direction);
|
||||||
|
|
||||||
|
const list = await db.result_profile.getPaginated(viewModel.get_page() - 1 < 0 ? 0 : viewModel.get_page(), viewModel.get_per_page(), where, order_by, direction, orderAssociations);
|
||||||
|
|
||||||
|
for (const item of list) {
|
||||||
|
if (item.output_variable_list) {
|
||||||
|
const parsedList = JSON.parse(item.output_variable_list);
|
||||||
|
let actualList = await db.output_variable.findAll({
|
||||||
|
where: {
|
||||||
|
id: parsedList,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
actualList = actualList.map((ov) => ov.name);
|
||||||
|
item.output_variable_list = actualList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.set_list(list);
|
||||||
|
|
||||||
|
if (format == "csv") {
|
||||||
|
const csv = viewModel.to_csv();
|
||||||
|
return res
|
||||||
|
.set({
|
||||||
|
"Content-Type": "text/csv",
|
||||||
|
"Content-Disposition": 'attachment; filename="export.csv"',
|
||||||
|
})
|
||||||
|
.send(csv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (format != 'view') {
|
||||||
|
// res.json(viewModel.to_json());
|
||||||
|
// } else {
|
||||||
|
// }
|
||||||
|
|
||||||
|
return res.render("admin/Result_profile", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Result_profile", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/admin/profile-sections-add", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
const resultProfileAdminAddViewModel = require("../../view_models/result_profile_admin_add_view_model");
|
||||||
|
|
||||||
|
const viewModel = new resultProfileAdminAddViewModel(db.result_profile, "Add result profile", "", "", "/admin/profile-sections");
|
||||||
|
viewModel.output_variables = await db.output_variable.getAll();
|
||||||
|
res.render("admin/Add_Result_profile", viewModel);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/admin/profile-sections-add", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
const resultProfileAdminAddViewModel = require("../../view_models/result_profile_admin_add_view_model");
|
||||||
|
|
||||||
|
const viewModel = new resultProfileAdminAddViewModel(db.result_profile, "Add result profile", "", "", "/admin/profile-sections");
|
||||||
|
viewModel.output_variables = await db.output_variable.getAll();
|
||||||
|
// TODO use separate controller for image upload
|
||||||
|
// {{{upload_field_setter}}}
|
||||||
|
|
||||||
|
const { section_title, output_variable_list = [] } = req.body;
|
||||||
|
|
||||||
|
viewModel.form_fields = {
|
||||||
|
...viewModel.form_fields,
|
||||||
|
section_title,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
viewModel.error = req.validationError;
|
||||||
|
return res.render("admin/Add_Result_profile", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
output_variable_list;
|
||||||
|
const data = await db.result_profile.insert({
|
||||||
|
section_title,
|
||||||
|
output_variable_list: !Array.isArray(output_variable_list) ? JSON.stringify([output_variable_list]) : JSON.stringify(output_variable_list),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Add_Result_profile", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
req.flash("success", "Result profile created successfully");
|
||||||
|
return res.redirect("/admin/profile-sections/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Add_Result_profile", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/admin/profile-sections-edit/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
const resultProfileAdminEditViewModel = require("../../view_models/result_profile_admin_edit_view_model");
|
||||||
|
|
||||||
|
const viewModel = new resultProfileAdminEditViewModel(db.result_profile, "Edit result profile", "", "", "/admin/profile-sections");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = await db.result_profile.getByPK(id);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
req.flash("error", "Result profile not found");
|
||||||
|
return res.redirect("/admin/profile-sections/0");
|
||||||
|
}
|
||||||
|
const values = exists;
|
||||||
|
Object.keys(viewModel.form_fields).forEach((field) => {
|
||||||
|
viewModel.form_fields[field] = values[field] || "";
|
||||||
|
});
|
||||||
|
if (viewModel.form_fields["output_variable_list"]) {
|
||||||
|
const parsedList = JSON.parse(viewModel.form_fields["output_variable_list"]);
|
||||||
|
let actualList = await db.output_variable.findAll({
|
||||||
|
where: {
|
||||||
|
id: parsedList,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
actualList = actualList.map((ov) => ov.name);
|
||||||
|
viewModel.form_fields["output_variable_list"] = actualList;
|
||||||
|
}
|
||||||
|
viewModel.output_variables = await db.output_variable.getAll();
|
||||||
|
return res.render("admin/Edit_Result_profile", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Result_profile", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/admin/profile-sections-edit/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
const resultProfileAdminEditViewModel = require("../../view_models/result_profile_admin_edit_view_model");
|
||||||
|
|
||||||
|
const viewModel = new resultProfileAdminEditViewModel(db.result_profile, "Edit result profile", "", "", "/admin/profile-sections");
|
||||||
|
|
||||||
|
let { section_title, output_variable_list = [] } = req.body;
|
||||||
|
|
||||||
|
viewModel.form_fields = {
|
||||||
|
...viewModel.form_fields,
|
||||||
|
section_title,
|
||||||
|
output_variable_list,
|
||||||
|
};
|
||||||
|
|
||||||
|
delete viewModel.form_fields.id;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
viewModel.error = req.validationError;
|
||||||
|
return res.render("admin/Edit_Result_profile", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
const resourceExists = await db.result_profile.getByPK(id);
|
||||||
|
if (!resourceExists) {
|
||||||
|
req.flash("error", "Result profile not found");
|
||||||
|
return res.redirect("/admin/profile-sections/0");
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
let data = await db.result_profile.edit(
|
||||||
|
{ section_title, output_variable_list: !Array.isArray(output_variable_list) ? JSON.stringify([output_variable_list]) : JSON.stringify(output_variable_list) },
|
||||||
|
id
|
||||||
|
);
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Result_profile", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
req.flash("success", "Result profile edited successfully");
|
||||||
|
|
||||||
|
return res.redirect("/admin/profile-sections/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Result_profile", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get(
|
||||||
|
"/admin/profile-sections-view/:id",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
|
||||||
|
async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const resultProfileAdminDetailViewModel = require("../../view_models/result_profile_admin_detail_view_model");
|
||||||
|
|
||||||
|
var viewModel = new resultProfileAdminDetailViewModel(db.result_profile, "Result profile details", "", "", "/admin/profile-sections");
|
||||||
|
|
||||||
|
const data = await db.result_profile.getByPK(id);
|
||||||
|
|
||||||
|
if (data["output_variable_list"]) {
|
||||||
|
const parsedList = JSON.parse(data["output_variable_list"]);
|
||||||
|
let actualList = await db.output_variable.findAll({
|
||||||
|
where: {
|
||||||
|
id: parsedList,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
actualList = actualList.map((ov) => ov.name);
|
||||||
|
data["output_variable_list"] = actualList;
|
||||||
|
}
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Result profile not found";
|
||||||
|
viewModel.detail_fields = { ...viewModel.detail_fields, id: "N/A", section_title: "N/A", output_variable_list: "N/A" };
|
||||||
|
} else {
|
||||||
|
viewModel.detail_fields = { ...viewModel.detail_fields, id: data["id"] || "N/A", section_title: data["section_title"] || "N/A", output_variable_list: data["output_variable_list"] || "N/A" };
|
||||||
|
}
|
||||||
|
|
||||||
|
res.render("admin/View_Result_profile", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
viewModel.detail_fields = { ...viewModel.detail_fields, id: "N/A", section_title: "N/A", output_variable_list: "N/A" };
|
||||||
|
res.render("admin/View_Result_profile", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get("/admin/profile-sections-delete/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const resultProfileAdminDeleteViewModel = require("../../view_models/result_profile_admin_delete_view_model");
|
||||||
|
|
||||||
|
const viewModel = new resultProfileAdminDeleteViewModel(db.result_profile);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = await db.result_profile.getByPK(id);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
req.flash("error", "Result profile not found");
|
||||||
|
return res.redirect("/admin/profile-sections/0");
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
await db.result_profile.realDelete(id);
|
||||||
|
|
||||||
|
req.flash("success", "Result profile was deleted successfully");
|
||||||
|
|
||||||
|
return res.redirect("/admin/profile-sections/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
req.flash("error", error.message || "Something went wrong");
|
||||||
|
return res.redirect("/admin/profile-sections/0");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// APIS
|
||||||
|
|
||||||
|
app.get("/admin/api/profile-sections", JwtService.verifyTokenMiddleware(role), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
const user_id = req.user_id;
|
||||||
|
const session = req.session;
|
||||||
|
let listViewModel = require("../../view_models/result_profile_admin_list_paginate_view_model");
|
||||||
|
let viewModel = new listViewModel(db.result_profile, "Profile sections", session.success, session.error, "/admin/profile-sections");
|
||||||
|
const direction = req.query.direction ? req.query.direction : "ASC";
|
||||||
|
const page = req.query.page ? parseInt(req.query.page) : 1;
|
||||||
|
const limit = req.query.limit ? parseInt(req.query.limit) : 10;
|
||||||
|
const offset = (page - 1) * limit;
|
||||||
|
let order_by = req.query.order_by ? req.query.order_by : viewModel.get_field_column()[0];
|
||||||
|
let orderAssociations = [];
|
||||||
|
viewModel.set_order_by(order_by);
|
||||||
|
let joins = order_by.includes(".") ? order_by.split(".") : [];
|
||||||
|
order_by = order_by.includes(".") ? joins[joins.length - 1] : order_by;
|
||||||
|
if (joins.length > 0) {
|
||||||
|
for (let i = joins.length - 1; i > 0; i--) {
|
||||||
|
orderAssociations.push(`${joins[i - 1]}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.set_id(req.query.id ? req.query.id : "");
|
||||||
|
viewModel.set_section_title(req.query.section_title ? req.query.section_title : "");
|
||||||
|
|
||||||
|
let where = helpers.filterEmptyFields({
|
||||||
|
id: viewModel.get_id(),
|
||||||
|
section_title: viewModel.get_section_title(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let include = [];
|
||||||
|
|
||||||
|
const { rows: allItems, count } = await db.result_profile.findAndCountAll({
|
||||||
|
where: where,
|
||||||
|
limit: limit == 0 ? null : limit,
|
||||||
|
offset: offset,
|
||||||
|
include: include,
|
||||||
|
distinct: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = {
|
||||||
|
items: allItems,
|
||||||
|
page,
|
||||||
|
nextPage: count > offset + limit ? page + 1 : false,
|
||||||
|
retrievedCount: allItems.length,
|
||||||
|
fullCount: count,
|
||||||
|
};
|
||||||
|
|
||||||
|
return res.status(201).json({ success: true, data: response });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return res.status(500).json({ success: false, message: error.message || "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/admin/api/profile-sections-add", JwtService.verifyTokenMiddleware(role), async function (req, res, next) {
|
||||||
|
const resultProfileAdminAddViewModel = require("../../view_models/result_profile_admin_add_view_model");
|
||||||
|
|
||||||
|
const viewModel = new resultProfileAdminAddViewModel(db.result_profile);
|
||||||
|
|
||||||
|
const { section_title, output_variable_list } = req.body;
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
return res.status(500).json({ success: false, message: req.validationError });
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await db.result_profile.insert({ section_title, output_variable_list });
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return res.status(500).json({ success: false, message: "Something went wrong" });
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(201).json({ success: true, message: "Result profile created successfully" });
|
||||||
|
} catch (error) {
|
||||||
|
return res.status(500).json({ success: false, message: "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.put("/admin/api/profile-sections-edit/:id", JwtService.verifyTokenMiddleware(role), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const resultProfileAdminEditViewModel = require("../../view_models/result_profile_admin_edit_view_model");
|
||||||
|
|
||||||
|
const viewModel = new resultProfileAdminEditViewModel(db.result_profile);
|
||||||
|
|
||||||
|
const { section_title, output_variable_list } = req.body;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
return res.status(500).json({ success: false, message: req.validationError });
|
||||||
|
}
|
||||||
|
|
||||||
|
const resourceExists = await db.result_profile.getByPK(id);
|
||||||
|
if (!resourceExists) {
|
||||||
|
return res.status(404).json({ success: false, message: "Result profile not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await db.result_profile.edit({ section_title, output_variable_list }, id);
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return res.status(500).json({ success: false, message: "Something went wrong" });
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.json({ success: true, message: "Result profile edited successfully" });
|
||||||
|
} catch (error) {
|
||||||
|
return res.status(500).json({ success: false, message: "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/admin/api/profile-sections-view/:id", JwtService.verifyTokenMiddleware(role), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const resultProfileAdminDetailViewModel = require("../../view_models/result_profile_admin_detail_view_model");
|
||||||
|
|
||||||
|
const viewModel = new resultProfileAdminDetailViewModel(db.result_profile);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await db.result_profile.getByPK(id);
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return res.status(404).json({ message: "Result profile not found", data: null });
|
||||||
|
} else {
|
||||||
|
const fields = { ...viewModel.detail_fields, id: data["id"] || "", section_title: data["section_title"] || "", output_variable_list: data["output_variable_list"] || "" };
|
||||||
|
return res.status(200).json({ data: fields });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return res.status(404).json({ message: "Something went wrong", data: null });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.delete("/admin/api/profile-sections-delete/:id", JwtService.verifyTokenMiddleware(role), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const resultProfileAdminDeleteViewModel = require("../../view_models/result_profile_admin_delete_view_model");
|
||||||
|
|
||||||
|
const viewModel = new resultProfileAdminDeleteViewModel(db.result_profile);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = await db.result_profile.getByPK(id);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
return res.status(404).json({ success: false, message: "Result profile not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.result_profile.realDelete(id);
|
||||||
|
|
||||||
|
return res.status(200).json({ success: true, message: "Result profile deleted successfully" });
|
||||||
|
} catch (error) {
|
||||||
|
return res.status(500).json({ success: false, message: "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
@@ -0,0 +1,353 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const app = require("express").Router();
|
||||||
|
const Sequelize = require("sequelize");
|
||||||
|
const logger = require("../../services/LoggingService");
|
||||||
|
let pagination = require("../../services/PaginationService");
|
||||||
|
let SessionService = require("../../services/SessionService");
|
||||||
|
let JwtService = require("../../services/JwtService");
|
||||||
|
const ValidationService = require("../../services/ValidationService");
|
||||||
|
const PermissionService = require("../../services/PermissionService");
|
||||||
|
const UploadService = require("../../services/UploadService");
|
||||||
|
const AuthService = require("../../services/AuthService");
|
||||||
|
const db = require("../../models");
|
||||||
|
const helpers = require("../../core/helpers");
|
||||||
|
|
||||||
|
const role = 1;
|
||||||
|
|
||||||
|
app.get("/admin/rules/:num", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
let session = req.session;
|
||||||
|
let paginateListViewModel = require("../../view_models/rules_admin_list_paginate_view_model");
|
||||||
|
|
||||||
|
var viewModel = new paginateListViewModel(db.rule, "Rules", session.success, session.error, "/admin/rules");
|
||||||
|
|
||||||
|
const format = req.query.format ? req.query.format : "view";
|
||||||
|
const direction = req.query.direction ? req.query.direction : "ASC";
|
||||||
|
const per_page = req.query.per_page ? req.query.per_page : 10;
|
||||||
|
let order_by = req.query.order_by ? req.query.order_by : viewModel.get_field_column()[0];
|
||||||
|
let orderAssociations = [];
|
||||||
|
viewModel.set_order_by(order_by);
|
||||||
|
let joins = order_by.includes(".") ? order_by.split(".") : [];
|
||||||
|
order_by = order_by.includes(".") ? joins[joins.length - 1] : order_by;
|
||||||
|
if (joins.length > 0) {
|
||||||
|
for (let i = joins.length - 1; i > 0; i--) {
|
||||||
|
orderAssociations.push(`${joins[i - 1]}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check for flash messages
|
||||||
|
const flashMessageSuccess = req.flash("success");
|
||||||
|
if (flashMessageSuccess && flashMessageSuccess.length > 0) {
|
||||||
|
viewModel.success = flashMessageSuccess[0];
|
||||||
|
}
|
||||||
|
const flashMessageError = req.flash("error");
|
||||||
|
if (flashMessageError && flashMessageError.length > 0) {
|
||||||
|
viewModel.error = flashMessageError[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.set_id(req.query.id ? req.query.id : "");
|
||||||
|
viewModel.set_operator(req.query.operator ? req.query.operator : "");
|
||||||
|
viewModel.set_action(req.query.action ? req.query.action : "");
|
||||||
|
viewModel.set_output_variable_name(req.query.output_variable_name ? req.query.output_variable_name : "");
|
||||||
|
|
||||||
|
let where = helpers.filterEmptyFields({
|
||||||
|
id: viewModel.get_id(),
|
||||||
|
operator: viewModel.get_operator(),
|
||||||
|
action: viewModel.get_action(),
|
||||||
|
output_variable_name: viewModel.get_output_variable_name(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const count = await db.rule._count(where, []);
|
||||||
|
|
||||||
|
viewModel.set_total_rows(count);
|
||||||
|
viewModel.set_per_page(+per_page);
|
||||||
|
viewModel.set_page(+req.params.num);
|
||||||
|
viewModel.set_query(req.query);
|
||||||
|
viewModel.set_sort_base_url(`/admin/rules/${+req.params.num}`);
|
||||||
|
viewModel.set_sort(direction);
|
||||||
|
|
||||||
|
const list = await db.rule.getPaginated(viewModel.get_page() - 1 < 0 ? 0 : viewModel.get_page(), viewModel.get_per_page(), where, order_by, direction, orderAssociations);
|
||||||
|
|
||||||
|
viewModel.set_list(list);
|
||||||
|
|
||||||
|
if (format == "csv") {
|
||||||
|
const csv = viewModel.to_csv();
|
||||||
|
return res
|
||||||
|
.set({
|
||||||
|
"Content-Type": "text/csv",
|
||||||
|
"Content-Disposition": 'attachment; filename="export.csv"',
|
||||||
|
})
|
||||||
|
.send(csv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (format != 'view') {
|
||||||
|
// res.json(viewModel.to_json());
|
||||||
|
// } else {
|
||||||
|
// }
|
||||||
|
|
||||||
|
return res.render("admin/Rules", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Rules", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/admin/rules-add", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rulesAdminAddViewModel = require("../../view_models/rules_admin_add_view_model");
|
||||||
|
|
||||||
|
const viewModel = new rulesAdminAddViewModel(db.rule, "Add rule", "", "", "/admin/rules");
|
||||||
|
viewModel.outputVariables = await db.output_variable.getAll();
|
||||||
|
viewModel.actives = await db.active.getAll();
|
||||||
|
res.render("admin/Add_Rules", viewModel);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post(
|
||||||
|
"/admin/rules-add",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
ValidationService.validateInput(
|
||||||
|
{ output_variable_name: "required", actives: "required", operator: "required", compare_value: "required", action: "required" },
|
||||||
|
{
|
||||||
|
"output_variable_name.required": "OutputVariableName is required",
|
||||||
|
"actives.required": "Actives is required",
|
||||||
|
"operator.required": "Operator is required",
|
||||||
|
"compare_value.required": "CompareValue is required",
|
||||||
|
"action.required": "Action is required",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
async function (req, res, next) {
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
const rulesAdminAddViewModel = require("../../view_models/rules_admin_add_view_model");
|
||||||
|
|
||||||
|
const viewModel = new rulesAdminAddViewModel(db.rule, "Add rule", "", "", "/admin/rules");
|
||||||
|
viewModel.outputVariables = await db.output_variable.getAll();
|
||||||
|
viewModel.actives = await db.active.getAll();
|
||||||
|
|
||||||
|
// TODO use separate controller for image upload
|
||||||
|
// {{{upload_field_setter}}}
|
||||||
|
|
||||||
|
let { output_variable_name, actives, operator, compare_value, min, max, action } = req.body;
|
||||||
|
if (!Array.isArray(actives)) {
|
||||||
|
actives = [actives];
|
||||||
|
}
|
||||||
|
viewModel.form_fields = {
|
||||||
|
...viewModel.form_fields,
|
||||||
|
output_variable_name,
|
||||||
|
actives,
|
||||||
|
operator,
|
||||||
|
compare_value,
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
action,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
viewModel.error = req.validationError;
|
||||||
|
return res.render("admin/Add_Rules", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
const data = await db.rule.insert({ output_variable_name, actives: JSON.stringify(actives), operator, compare_value, min, max, action });
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Add_Rules", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
req.flash("success", "Rule created successfully");
|
||||||
|
return res.redirect("/admin/rules/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Add_Rules", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get("/admin/rules-edit/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
const rulesAdminEditViewModel = require("../../view_models/rules_admin_edit_view_model");
|
||||||
|
|
||||||
|
const viewModel = new rulesAdminEditViewModel(db.rule, "Edit rule", "", "", "/admin/rules");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = await db.rule.getByPK(id);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
req.flash("error", "Rule not found");
|
||||||
|
return res.redirect("/admin/rules/0");
|
||||||
|
}
|
||||||
|
const values = exists;
|
||||||
|
Object.keys(viewModel.form_fields).forEach((field) => {
|
||||||
|
viewModel.form_fields[field] = values[field] || "";
|
||||||
|
});
|
||||||
|
|
||||||
|
viewModel.outputVariables = await db.output_variable.getAll();
|
||||||
|
viewModel.actives = await db.active.getAll();
|
||||||
|
return res.render("admin/Edit_Rules", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Rules", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post(
|
||||||
|
"/admin/rules-edit/:id",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
ValidationService.validateInput(
|
||||||
|
{ output_variable_name: "required", actives: "required", operator: "required", compare_value: "required", action: "required" },
|
||||||
|
{
|
||||||
|
"output_variable_name.required": "OutputVariableName is required",
|
||||||
|
"actives.required": "Actives is required",
|
||||||
|
"operator.required": "Operator is required",
|
||||||
|
"compare_value.required": "CompareValue is required",
|
||||||
|
"action.required": "Action is required",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rulesAdminEditViewModel = require("../../view_models/rules_admin_edit_view_model");
|
||||||
|
|
||||||
|
const viewModel = new rulesAdminEditViewModel(db.rule, "Edit rule", "", "", "/admin/rules");
|
||||||
|
|
||||||
|
viewModel.outputVariables = await db.output_variable.getAll();
|
||||||
|
viewModel.actives = await db.active.getAll();
|
||||||
|
let { output_variable_name, actives, operator, compare_value, min, max, action } = req.body;
|
||||||
|
if (!Array.isArray(actives)) {
|
||||||
|
actives = [actives];
|
||||||
|
}
|
||||||
|
viewModel.form_fields = {
|
||||||
|
...viewModel.form_fields,
|
||||||
|
output_variable_name,
|
||||||
|
actives,
|
||||||
|
operator,
|
||||||
|
compare_value,
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
action,
|
||||||
|
};
|
||||||
|
|
||||||
|
delete viewModel.form_fields.id;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
viewModel.error = req.validationError;
|
||||||
|
return res.render("admin/Edit_Rules", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
const resourceExists = await db.rule.getByPK(id);
|
||||||
|
if (!resourceExists) {
|
||||||
|
req.flash("error", "Rule not found");
|
||||||
|
return res.redirect("/admin/rules/0");
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
let data = await db.rule.edit({ output_variable_name, actives: JSON.stringify(actives), operator, compare_value, min, max, action }, id);
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Rules", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
req.flash("success", "Rule edited successfully");
|
||||||
|
|
||||||
|
return res.redirect("/admin/rules/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Rules", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get(
|
||||||
|
"/admin/rules-view/:id",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
|
||||||
|
async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const rulesAdminDetailViewModel = require("../../view_models/rules_admin_detail_view_model");
|
||||||
|
|
||||||
|
var viewModel = new rulesAdminDetailViewModel(db.rule, "Rule details", "", "", "/admin/rules");
|
||||||
|
|
||||||
|
const data = await db.rule.getByPK(id);
|
||||||
|
data.operator = db.rule.operator_mapping()[data.operator];
|
||||||
|
data.action = db.rule.action_mapping()[data.action];
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Rule not found";
|
||||||
|
viewModel.detail_fields = { ...viewModel.detail_fields, id: "N/A", output_variable_name: "N/A", actives: "N/A", operator: "N/A", compare_value: "N/A", min: "N/A", max: "N/A", action: "N/A" };
|
||||||
|
} else {
|
||||||
|
viewModel.detail_fields = {
|
||||||
|
...viewModel.detail_fields,
|
||||||
|
id: data["id"] || "N/A",
|
||||||
|
output_variable_name: data["output_variable_name"] || "N/A",
|
||||||
|
actives: data["actives"] || "N/A",
|
||||||
|
operator: data["operator"] || "N/A",
|
||||||
|
compare_value: data["compare_value"] || "N/A",
|
||||||
|
min: data["min"] || "N/A",
|
||||||
|
max: data["max"] || "N/A",
|
||||||
|
action: data["action"] || "N/A",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
res.render("admin/View_Rules", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
viewModel.detail_fields = { ...viewModel.detail_fields, id: "N/A", output_variable_name: "N/A", actives: "N/A", operator: "N/A", compare_value: "N/A", min: "N/A", max: "N/A", action: "N/A" };
|
||||||
|
res.render("admin/View_Rules", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get("/admin/rules-delete/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const rulesAdminDeleteViewModel = require("../../view_models/rules_admin_delete_view_model");
|
||||||
|
|
||||||
|
const viewModel = new rulesAdminDeleteViewModel(db.rule);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = await db.rule.getByPK(id);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
req.flash("error", "Rule not found");
|
||||||
|
return res.redirect("/admin/rules/0");
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
await db.rule.realDelete(id);
|
||||||
|
|
||||||
|
req.flash("success", "Rule was deleted successfully");
|
||||||
|
|
||||||
|
return res.redirect("/admin/rules/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
req.flash("error", error.message || "Something went wrong");
|
||||||
|
return res.redirect("/admin/rules/0");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// APIS
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
@@ -0,0 +1,342 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const app = require("express").Router();
|
||||||
|
const Sequelize = require("sequelize");
|
||||||
|
const logger = require("../../services/LoggingService");
|
||||||
|
let pagination = require("../../services/PaginationService");
|
||||||
|
let SessionService = require("../../services/SessionService");
|
||||||
|
let JwtService = require("../../services/JwtService");
|
||||||
|
const ValidationService = require("../../services/ValidationService");
|
||||||
|
const PermissionService = require("../../services/PermissionService");
|
||||||
|
const UploadService = require("../../services/UploadService");
|
||||||
|
const AuthService = require("../../services/AuthService");
|
||||||
|
const db = require("../../models");
|
||||||
|
const helpers = require("../../core/helpers");
|
||||||
|
|
||||||
|
const role = 1;
|
||||||
|
|
||||||
|
app.get("/admin/users/:num", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
let session = req.session;
|
||||||
|
let paginateListViewModel = require("../../view_models/users_admin_list_paginate_view_model");
|
||||||
|
|
||||||
|
var viewModel = new paginateListViewModel(db.user, "Users", session.success, session.error, "/admin/users");
|
||||||
|
|
||||||
|
const format = req.query.format ? req.query.format : "view";
|
||||||
|
const direction = req.query.direction ? req.query.direction : "ASC";
|
||||||
|
const per_page = req.query.per_page ? req.query.per_page : 10;
|
||||||
|
let order_by = req.query.order_by ? req.query.order_by : viewModel.get_field_column()[0];
|
||||||
|
let orderAssociations = [];
|
||||||
|
viewModel.set_order_by(order_by);
|
||||||
|
let joins = order_by.includes(".") ? order_by.split(".") : [];
|
||||||
|
order_by = order_by.includes(".") ? joins[joins.length - 1] : order_by;
|
||||||
|
if (joins.length > 0) {
|
||||||
|
for (let i = joins.length - 1; i > 0; i--) {
|
||||||
|
orderAssociations.push(`${joins[i - 1]}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check for flash messages
|
||||||
|
const flashMessageSuccess = req.flash("success");
|
||||||
|
if (flashMessageSuccess && flashMessageSuccess.length > 0) {
|
||||||
|
viewModel.success = flashMessageSuccess[0];
|
||||||
|
}
|
||||||
|
const flashMessageError = req.flash("error");
|
||||||
|
if (flashMessageError && flashMessageError.length > 0) {
|
||||||
|
viewModel.error = flashMessageError[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.set_id(req.query.id ? req.query.id : "");
|
||||||
|
viewModel.set_credential_email(req.query.credential_email ? req.query.credential_email : "");
|
||||||
|
viewModel.set_first_name(req.query.first_name ? req.query.first_name : "");
|
||||||
|
viewModel.set_last_name(req.query.last_name ? req.query.last_name : "");
|
||||||
|
|
||||||
|
let where = helpers.filterEmptyFields({
|
||||||
|
id: viewModel.get_id(),
|
||||||
|
first_name: viewModel.get_first_name(),
|
||||||
|
last_name: viewModel.get_last_name(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let associatedWhere = helpers.filterEmptyFields({
|
||||||
|
email: viewModel.get_credential_email(),
|
||||||
|
});
|
||||||
|
const isAssociationRequired = Object.keys(associatedWhere).length > 0 ? true : false;
|
||||||
|
|
||||||
|
const count = await db.user._count(where, [{ model: db.credential, where: associatedWhere, required: isAssociationRequired, as: "credential" }]);
|
||||||
|
|
||||||
|
viewModel.set_total_rows(count);
|
||||||
|
viewModel.set_per_page(+per_page);
|
||||||
|
viewModel.set_page(+req.params.num);
|
||||||
|
viewModel.set_query(req.query);
|
||||||
|
viewModel.set_sort_base_url(`/admin/users/${+req.params.num}`);
|
||||||
|
viewModel.set_sort(direction);
|
||||||
|
|
||||||
|
const list = await db.user.get_credential_paginated(
|
||||||
|
db,
|
||||||
|
associatedWhere,
|
||||||
|
viewModel.get_page() - 1 < 0 ? 0 : viewModel.get_page(),
|
||||||
|
viewModel.get_per_page(),
|
||||||
|
where,
|
||||||
|
order_by,
|
||||||
|
direction,
|
||||||
|
orderAssociations
|
||||||
|
);
|
||||||
|
|
||||||
|
viewModel.set_list(list);
|
||||||
|
|
||||||
|
viewModel.credential = await db.credential;
|
||||||
|
|
||||||
|
if (format == "csv") {
|
||||||
|
const csv = viewModel.to_csv();
|
||||||
|
return res
|
||||||
|
.set({
|
||||||
|
"Content-Type": "text/csv",
|
||||||
|
"Content-Disposition": 'attachment; filename="export.csv"',
|
||||||
|
})
|
||||||
|
.send(csv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (format != 'view') {
|
||||||
|
// res.json(viewModel.to_json());
|
||||||
|
// } else {
|
||||||
|
// }
|
||||||
|
|
||||||
|
return res.render("admin/Users", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Users", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/admin/users-add", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
const usersAdminAddViewModel = require("../../view_models/users_admin_add_view_model");
|
||||||
|
|
||||||
|
const viewModel = new usersAdminAddViewModel(db.user, "Add user", "", "", "/admin/users");
|
||||||
|
|
||||||
|
res.render("admin/Add_Users", viewModel);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post(
|
||||||
|
"/admin/users-add",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
ValidationService.validateInput(
|
||||||
|
{ first_name: "required", last_name: "required", status: "required" },
|
||||||
|
{ "first_name.required": "FirstName is required", "last_name.required": "LastName is required", "status.required": "Status is required" }
|
||||||
|
),
|
||||||
|
async function (req, res, next) {
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
const usersAdminAddViewModel = require("../../view_models/users_admin_add_view_model");
|
||||||
|
|
||||||
|
const viewModel = new usersAdminAddViewModel(db.user, "Add user", "", "", "/admin/users");
|
||||||
|
|
||||||
|
// TODO use separate controller for image upload
|
||||||
|
// {{{upload_field_setter}}}
|
||||||
|
|
||||||
|
const { email, password, first_name, last_name, image, role_id, phone, status } = req.body;
|
||||||
|
|
||||||
|
viewModel.form_fields = {
|
||||||
|
...viewModel.form_fields,
|
||||||
|
email,
|
||||||
|
password,
|
||||||
|
first_name,
|
||||||
|
last_name,
|
||||||
|
image,
|
||||||
|
role_id,
|
||||||
|
phone,
|
||||||
|
status,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
viewModel.error = req.validationError;
|
||||||
|
return res.render("admin/Add_Users", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
const { email, password = "", role_id, ...rest } = viewModel.form_fields;
|
||||||
|
const data = await AuthService.register(email, password, role_id, rest);
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Add_Users", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.activity_log.insert({
|
||||||
|
action: "ADD",
|
||||||
|
name: "Admin_user_controller.js",
|
||||||
|
portal: "admin",
|
||||||
|
data: JSON.stringify({ email, password, first_name, last_name, image, role_id, phone, status }),
|
||||||
|
});
|
||||||
|
|
||||||
|
req.flash("success", "User created successfully");
|
||||||
|
return res.redirect("/admin/users/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Add_Users", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get("/admin/users-edit/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
const usersAdminEditViewModel = require("../../view_models/users_admin_edit_view_model");
|
||||||
|
|
||||||
|
const viewModel = new usersAdminEditViewModel(db.user, "Edit user", "", "", "/admin/users");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = await db.user.get_user_credential(id, db);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
req.flash("error", "User not found");
|
||||||
|
return res.redirect("/admin/users/0");
|
||||||
|
}
|
||||||
|
const values = exists;
|
||||||
|
Object.keys(viewModel.form_fields).forEach((field) => {
|
||||||
|
if (field === "credential.email") {
|
||||||
|
viewModel.form_fields[field] = values["credential"]["email"];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (field === "credential.password") {
|
||||||
|
viewModel.form_fields[field] = values["credential"]["password"];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
viewModel.form_fields[field] = values[field] || "";
|
||||||
|
});
|
||||||
|
viewModel.credential = db.credential;
|
||||||
|
return res.render("admin/Edit_Users", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Users", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/admin/users-edit/:id", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
let id = req.params.id;
|
||||||
|
if (req.session.csrf === undefined) {
|
||||||
|
req.session.csrf = SessionService.randomString(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
const usersAdminEditViewModel = require("../../view_models/users_admin_edit_view_model");
|
||||||
|
|
||||||
|
const viewModel = new usersAdminEditViewModel(db.user, "Edit user", "", "", "/admin/users");
|
||||||
|
|
||||||
|
const { credential_email, credential_password, first_name, last_name, role_id, image, phone, status } = req.body;
|
||||||
|
|
||||||
|
viewModel.form_fields = {
|
||||||
|
...viewModel.form_fields,
|
||||||
|
"credential.email": credential_email,
|
||||||
|
"credential.password": credential_password,
|
||||||
|
first_name,
|
||||||
|
last_name,
|
||||||
|
role_id,
|
||||||
|
image,
|
||||||
|
phone,
|
||||||
|
status,
|
||||||
|
};
|
||||||
|
|
||||||
|
delete viewModel.form_fields.id;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (req.validationError) {
|
||||||
|
viewModel.error = req.validationError;
|
||||||
|
return res.render("admin/Edit_Users", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
const resourceExists = await db.user.get_user_credential(id, db);
|
||||||
|
if (!resourceExists) {
|
||||||
|
req.flash("error", "User not found");
|
||||||
|
return res.redirect("/admin/users/0");
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.session = req.session;
|
||||||
|
|
||||||
|
let data = await db.user.edit({ first_name, last_name, role_id, image, phone, status }, id);
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Users", viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resourceExists.credential) {
|
||||||
|
data = await db.credential.edit(helpers.filterEmptyFields({ email: credential_email, password: credential_password }), resourceExists.credential.id);
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Users", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.activity_log.insert({
|
||||||
|
action: "EDIT",
|
||||||
|
name: "Admin_user_controller.js",
|
||||||
|
portal: "admin",
|
||||||
|
data: JSON.stringify({ credential_email, credential_password, first_name, last_name, role_id, image, phone, status }),
|
||||||
|
});
|
||||||
|
|
||||||
|
req.flash("success", "User edited successfully");
|
||||||
|
|
||||||
|
return res.redirect("/admin/users/0");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
return res.render("admin/Edit_Users", viewModel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get(
|
||||||
|
"/admin/users-view/:id",
|
||||||
|
SessionService.verifySessionMiddleware(role, "admin"),
|
||||||
|
|
||||||
|
async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
let id = req.params.id;
|
||||||
|
|
||||||
|
const usersAdminDetailViewModel = require("../../view_models/users_admin_detail_view_model");
|
||||||
|
|
||||||
|
var viewModel = new usersAdminDetailViewModel(db.user, "User details", "", "", "/admin/users");
|
||||||
|
|
||||||
|
const data = await db.user.get_user_credential(id, db);
|
||||||
|
data.status = db.user.status_mapping()[data.status];
|
||||||
|
data["credential.two_factor_authentication"] = db.credential.two_factor_authentication_mapping()[data.credential.two_factor_authentication];
|
||||||
|
data["credential.type"] = db.credential.type_mapping()[data.credential.type];
|
||||||
|
data["credential.status"] = db.credential.status_mapping()[data.credential.status];
|
||||||
|
data["credential.verify"] = db.credential.verify_mapping()[data.credential.verify];
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
viewModel.error = "User not found";
|
||||||
|
viewModel.detail_fields = { ...viewModel.detail_fields, id: "N/A", "credential.email": "N/A", first_name: "N/A", last_name: "N/A", role_id: "N/A", status: "N/A" };
|
||||||
|
} else {
|
||||||
|
viewModel.detail_fields = {
|
||||||
|
...viewModel.detail_fields,
|
||||||
|
id: data["id"] || "N/A",
|
||||||
|
"credential.email": data["credential"]["email"] || "N/A",
|
||||||
|
first_name: data["first_name"] || "N/A",
|
||||||
|
last_name: data["last_name"] || "N/A",
|
||||||
|
role_id: data["role_id"] || "N/A",
|
||||||
|
status: data["status"] || "N/A",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
res.render("admin/View_Users", viewModel);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
viewModel.error = error.message || "Something went wrong";
|
||||||
|
viewModel.detail_fields = { ...viewModel.detail_fields, id: "N/A", "credential.email": "N/A", first_name: "N/A", last_name: "N/A", role_id: "N/A", status: "N/A" };
|
||||||
|
res.render("admin/View_Users", viewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// APIS
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
const SessionService = require("../../services/SessionService");
|
||||||
|
const app = require("express").Router();
|
||||||
|
const db = require("../../models");
|
||||||
|
const role = 1;
|
||||||
|
|
||||||
|
app.get("/admin/letters/main", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
const { order: orderId } = req.query;
|
||||||
|
// const orderId = 2;
|
||||||
|
const order = await db.order.getByPK(orderId);
|
||||||
|
const firstName = JSON.parse(order.customer).first_name;
|
||||||
|
res.render("admin/Letters/Main_Letter", {
|
||||||
|
firstName,
|
||||||
|
get_page_name: () => "Letter",
|
||||||
|
_base_url: "/admin/letters/main",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/admin/letters/profile", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
const { order: orderId } = req.query;
|
||||||
|
|
||||||
|
const order = await db.order.getByPK(orderId);
|
||||||
|
const firstName = order.customer ? JSON.parse(order.customer).first_name ?? null : null;
|
||||||
|
const profileCharcteristics = order.profile ? JSON.parse(order.profile) : [];
|
||||||
|
res.render("admin/Letters/Profile_Letter", { firstName, profileCharcteristics, get_page_name: () => "Letter", _base_url: "/admin/letters/profile" });
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/admin/letters/formula", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
const { order: orderId } = req.query;
|
||||||
|
|
||||||
|
const order = await db.order.getByPK(orderId);
|
||||||
|
let activesNames = order.actives ? JSON.parse(order.actives) : [];
|
||||||
|
if (activesNames && activesNames.length) activesNames = activesNames.filter((active) => active !== "Base");
|
||||||
|
const { rows: actives, count } = await db.active.findAndCountAll({
|
||||||
|
where: { name: { [db.Sequelize.Op.in]: activesNames } },
|
||||||
|
});
|
||||||
|
|
||||||
|
res.render("admin/Letters/Formula_Letter", { actives, count, get_page_name: () => "Letter", _base_url: "/admin/letters/formula" });
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/admin/letters/instructions", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
const { order: orderId } = req.query;
|
||||||
|
|
||||||
|
const order = await db.order.getByPK(orderId);
|
||||||
|
|
||||||
|
res.render("admin/Letters/Instructions_Letter", { get_page_name: () => "Letter", _base_url: "/admin/letters/instructions" });
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/admin/letters/all", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
const { order: orderId } = req.query;
|
||||||
|
|
||||||
|
const order = await db.order.getByPK(orderId);
|
||||||
|
|
||||||
|
const firstName = JSON.parse(order.customer).first_name;
|
||||||
|
const profileCharcteristics = order.profile ? JSON.parse(order.profile) : [];
|
||||||
|
|
||||||
|
let activesNames = order.actives ? JSON.parse(order.actives) : [];
|
||||||
|
if (activesNames && activesNames.length) activesNames = activesNames.filter((active) => active !== "Base");
|
||||||
|
const { rows: actives, count } = await db.active.findAndCountAll({
|
||||||
|
where: { name: { [db.Sequelize.Op.in]: activesNames } },
|
||||||
|
});
|
||||||
|
|
||||||
|
res.render("admin/Letters/All", { firstName, profileCharcteristics, actives, count, get_page_name: () => "Letter", _base_url: "/admin/letters/all" });
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/admin/dashboard", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
const config = await db.configuration.findOne({ where: { id: 1 }, include: [{ model: db.image, as: "image" }] });
|
||||||
|
res.render("admin/Dashboard", {
|
||||||
|
config,
|
||||||
|
get_page_name: () => "Dashboard",
|
||||||
|
_base_url: "/admin/dashboard",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/questions/order/save", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
const questions = req.body;
|
||||||
|
|
||||||
|
for (const question of questions) {
|
||||||
|
if (question.id && question.order) {
|
||||||
|
await db.question.edit({ order: question.order }, question.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.json({ success: true, message: "Successfully updated orders" });
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
return res.status(500).json({ success: false, message: "Failed to update orders" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
app.post("/main-image/update", SessionService.verifySessionMiddleware(role, "admin"), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
const { image_url } = req.body;
|
||||||
|
await db.configuration.edit({ image_id: image_url }, 1);
|
||||||
|
return res.json({ success: true, message: "Successfully updated image" });
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
return res.status(500).json({ success: false, message: "Failed to update image" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/configurations", async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
const config = await db.configuration.findOne({ where: { id: 1 }, include: [{ model: db.image, as: "image" }] });
|
||||||
|
if (!config) {
|
||||||
|
return res.status(404).json({ success: false, message: "No configurations found" });
|
||||||
|
}
|
||||||
|
return res.json({ success: true, payload: config });
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
return res.status(500).json({ success: false, message: "Failed to fetch configurations" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const app = require("express").Router();
|
||||||
|
// const Sequelize = require('sequelize');
|
||||||
|
// const logger = require('../../services/LoggingService');
|
||||||
|
// let pagination = require('../../services/PaginationService');
|
||||||
|
// let SessionService = require('../../services/SessionService');
|
||||||
|
let JwtService = require("../../services/JwtService");
|
||||||
|
const ValidationService = require("../../services/ValidationService");
|
||||||
|
// const PermissionService = require('../../services/PermissionService');
|
||||||
|
// const UploadService = require('../../services/UploadService');
|
||||||
|
// const AuthService = require('../../services/AuthService');
|
||||||
|
const db = require("../../models");
|
||||||
|
const helpers = require("../../core/helpers");
|
||||||
|
|
||||||
|
const role = 1;
|
||||||
|
|
||||||
|
app.get("/admin/api/profile-system", async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
const { rows: allItems, count } = await db.profile_header.findAndCountAll({
|
||||||
|
offset: offset,
|
||||||
|
order: [["id", direction]],
|
||||||
|
distinct: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = {
|
||||||
|
items: allItems,
|
||||||
|
count,
|
||||||
|
};
|
||||||
|
|
||||||
|
return res.status(201).json({ success: true, data: response });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return res.status(500).json({ success: false, message: error.message || "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
module.exports = app;
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
const AdminUserController = require("./admin/Admin_user_controller");
|
||||||
|
const Admin_order_controller = require("./admin/Admin_order_controller");
|
||||||
|
const AdminQuizController = require("./admin/Admin_quiz_controller");
|
||||||
|
const AdminQuestionController = require("./admin/Admin_question_controller");
|
||||||
|
const AdminRulesController = require("./admin/Admin_rules_controller");
|
||||||
|
const AdminActivesController = require("./admin/Admin_actives_controller");
|
||||||
|
const AdminOutputVariablesController = require("./admin/Admin_output_variables_controller");
|
||||||
|
const AdminResultProfileController = require("./admin/Admin_result_profile_controller");
|
||||||
|
const AdminGetProfileSystem = require("./admin/getProfileSystem");
|
||||||
|
const PublicIndex = require("./public/index");
|
||||||
|
const AdminAnswerController = require("./admin/Admin_answer_controller");
|
||||||
|
const AdminDashboard = require("./admin/Dashboard");
|
||||||
|
const MemberDashboard = require("./member/Dashboard");
|
||||||
|
const getProducts = require("./shopify/getProducts");
|
||||||
|
const ShopifyWebhook = require("./shopify/webhook");
|
||||||
|
const KlaviyoController = require("./klaviyo/index");
|
||||||
|
module.exports = [
|
||||||
|
KlaviyoController,
|
||||||
|
Admin_order_controller,
|
||||||
|
ShopifyWebhook,
|
||||||
|
AdminResultProfileController,
|
||||||
|
AdminGetProfileSystem,
|
||||||
|
AdminUserController,
|
||||||
|
AdminQuizController,
|
||||||
|
AdminQuestionController,
|
||||||
|
AdminRulesController,
|
||||||
|
AdminActivesController,
|
||||||
|
AdminOutputVariablesController,
|
||||||
|
AdminAnswerController,
|
||||||
|
AdminDashboard,
|
||||||
|
MemberDashboard,
|
||||||
|
PublicIndex,
|
||||||
|
getProducts,
|
||||||
|
];
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
// const SessionService = require('../../services/SessionService');
|
||||||
|
const app = require("express").Router();
|
||||||
|
const db = require("../../models");
|
||||||
|
const axios = require("axios");
|
||||||
|
const cors = require("cors");
|
||||||
|
|
||||||
|
const quiz_list_id = "SuMRRB";
|
||||||
|
const klaviyo_api_key = "pk_026fc9c97c646a73a053c99ef8d8c9c53d";
|
||||||
|
const corsOptions = {
|
||||||
|
origin: ["http://localhost:3001"],
|
||||||
|
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
|
||||||
|
};
|
||||||
|
|
||||||
|
//api: get output variable info
|
||||||
|
app.post("/klaviyo/identity", cors(corsOptions), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
//body should have actives lsit as array
|
||||||
|
const { email, firstName, lastName } = req.body;
|
||||||
|
let data = JSON.stringify({
|
||||||
|
token: klaviyo_api_key,
|
||||||
|
properties: {
|
||||||
|
$email: email,
|
||||||
|
$first_name: firstName,
|
||||||
|
$last_name: lastName,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let config = {
|
||||||
|
method: "post",
|
||||||
|
url: "https://a.klaviyo.com/api/identify",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await axios(config);
|
||||||
|
console.log(response.data);
|
||||||
|
|
||||||
|
return res.status(201).json({ success: true, payload: response.data });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return res.status(500).json({ success: false, message: error.message || "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/klaviyo/list", cors(corsOptions), async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
//body should have actives lsit as array
|
||||||
|
const { email } = req.body;
|
||||||
|
let data = JSON.stringify({
|
||||||
|
profiles: [
|
||||||
|
{
|
||||||
|
email: email,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
let config = {
|
||||||
|
method: "post",
|
||||||
|
url: `https://a.klaviyo.com/api/v2/list/${quiz_list_id}/members?api_key=${klaviyo_api_key}`,
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await axios(config);
|
||||||
|
console.log(response.data);
|
||||||
|
|
||||||
|
return res.status(201).json({ success: true, payload: response.data });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return res.status(500).json({ success: false, message: error.message || "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
const SessionService = require('../../services/SessionService');
|
||||||
|
const app = require('express').Router();
|
||||||
|
|
||||||
|
const role = 2;
|
||||||
|
|
||||||
|
app.get(
|
||||||
|
"/member/dashboard",
|
||||||
|
SessionService.verifySessionMiddleware(role,"member"),
|
||||||
|
async function (req, res, next) {
|
||||||
|
|
||||||
|
res.render('member/Dashboard',{
|
||||||
|
get_page_name: () => 'Dashboard',
|
||||||
|
_base_url: '/member/dashboard',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
@@ -0,0 +1,320 @@
|
|||||||
|
// const SessionService = require('../../services/SessionService');
|
||||||
|
const app = require("express").Router();
|
||||||
|
const db = require("../../models");
|
||||||
|
const axios = require("axios");
|
||||||
|
|
||||||
|
//api: get output variable info
|
||||||
|
app.get("/api/v1/output-variable/:name", async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
//body should have actives lsit as array
|
||||||
|
const { name } = req.params;
|
||||||
|
|
||||||
|
const outputVariable = await db.output_variable.getByFields({ name });
|
||||||
|
if (!outputVariable) {
|
||||||
|
return res.status(404).json({ success: false, message: `Output variable of that name ${name} is not found.` });
|
||||||
|
}
|
||||||
|
let payload = {},
|
||||||
|
actives = [];
|
||||||
|
if (outputVariable.active_list) {
|
||||||
|
let activeList = JSON.parse(outputVariable.active_list);
|
||||||
|
for (const activeId of activeList) {
|
||||||
|
const active = await db.active.getByPK(activeId);
|
||||||
|
if (active) {
|
||||||
|
actives.push(active.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
payload = { name: outputVariable.name, actives: actives, ranges_response: JSON.parse(outputVariable.ranges_response) };
|
||||||
|
|
||||||
|
return res.status(201).json({ success: true, data: payload });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return res.status(500).json({ success: false, message: error.message || "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/api/v1/output-variables/actives-list", async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
//body should have actives lsit as array
|
||||||
|
const { names_list } = req.query;
|
||||||
|
if (!names_list) {
|
||||||
|
return res.status(401).json({ success: false, message: "Empty list" });
|
||||||
|
}
|
||||||
|
const outputVariablesList = names_list.split(",");
|
||||||
|
|
||||||
|
const outputVars = await db.output_variable.findAll({
|
||||||
|
where: {
|
||||||
|
name: outputVariablesList,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let allActivesList = [];
|
||||||
|
outputVars.forEach((outputVar) => {
|
||||||
|
if (outputVar.active_list) {
|
||||||
|
let parsedList = JSON.parse(outputVar.active_list);
|
||||||
|
if (parsedList.length) {
|
||||||
|
parsedList.forEach((item) => {
|
||||||
|
if (!allActivesList.includes(item)) {
|
||||||
|
allActivesList.push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let actives = await db.active
|
||||||
|
.findAll({
|
||||||
|
where: {
|
||||||
|
id: allActivesList,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
return data.map((item) => {
|
||||||
|
return item.name;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
if (!actives) {
|
||||||
|
return res.status(404).json({ success: false, message: "No actives found for this list" });
|
||||||
|
}
|
||||||
|
return res.status(201).json({ success: true, data: actives });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return res.status(500).json({ success: false, message: error.message || "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/api/v1/places/autocomplete", async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
const { input } = req.query;
|
||||||
|
|
||||||
|
var config = {
|
||||||
|
method: "get",
|
||||||
|
// url: `https://maps.googleapis.com/maps/api/place/autocomplete/json?input=${encodeURIComponent(input)}&types=(regions)&key=${process.env.GOOGLE_PLACES_API_KEY}`,
|
||||||
|
url: `https://maps.googleapis.com/maps/api/place/autocomplete/json?input=${encodeURIComponent(input)}&key=${process.env.GOOGLE_PLACES_API_KEY}`,
|
||||||
|
headers: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await axios(config).then(function (response) {
|
||||||
|
return response.data;
|
||||||
|
});
|
||||||
|
const payload = response.predictions.map((prediction) => {
|
||||||
|
return {
|
||||||
|
name: prediction.description,
|
||||||
|
id: prediction.place_id,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(201).json(payload);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return res.status(500).json({ success: false, message: error.message || "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
app.get("/api/v1/rules", async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
//body should have actives lsit as array
|
||||||
|
const rules = await db.rule.getAll();
|
||||||
|
|
||||||
|
if (!rules) {
|
||||||
|
return res.status(404).json({ success: false, message: `There are no rules` });
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(201).json({ success: true, data: rules });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return res.status(500).json({ success: false, message: error.message || "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/api/v1/profile-sections", async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
//body should have actives lsit as array
|
||||||
|
const profileSections = await db.result_profile.getAll();
|
||||||
|
|
||||||
|
if (!profileSections) {
|
||||||
|
return res.status(404).json({ success: false, message: `There are sections to display` });
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const section of profileSections) {
|
||||||
|
if (section.output_variable_list) {
|
||||||
|
const parsedList = JSON.parse(section.output_variable_list);
|
||||||
|
let actualList = await db.output_variable.findAll({
|
||||||
|
where: {
|
||||||
|
id: parsedList,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
actualList = actualList.map((ov) => ov.name);
|
||||||
|
section.output_variable_list = actualList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.status(201).json({ success: true, data: profileSections });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return res.status(500).json({ success: false, message: error.message || "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/api/v1/weather-profile", async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
const { city_id } = req.query;
|
||||||
|
var config = {
|
||||||
|
method: "get",
|
||||||
|
url: `https://maps.googleapis.com/maps/api/place/details/json?place_id=${city_id}&fields=geometry,formatted_address,address_component&key=${process.env.GOOGLE_PLACES_API_KEY}`,
|
||||||
|
headers: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
const place_details = await axios(config);
|
||||||
|
// .then((response) => response.data);
|
||||||
|
if (place_details?.data?.status !== "OK") {
|
||||||
|
console.error(place_details);
|
||||||
|
return res.status(400).json({ success: false, message: "Can't get location" });
|
||||||
|
}
|
||||||
|
const lon = place_details.data.result.geometry.location.lng;
|
||||||
|
const lat = place_details.data.result.geometry.location.lat;
|
||||||
|
const country = place_details.data.result.address_components.find((adr) => adr.types.includes("country"));
|
||||||
|
// const country;
|
||||||
|
config = {
|
||||||
|
method: "get",
|
||||||
|
url: `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${process.env.OPEN_WEATHER_API_KEY}&units=metric`,
|
||||||
|
};
|
||||||
|
|
||||||
|
const weather = await axios(config).then((response) => response.data);
|
||||||
|
|
||||||
|
config = {
|
||||||
|
method: "get",
|
||||||
|
url: `https://api.openweathermap.org/data/2.5/air_pollution?lat=${lat}&lon=${lon}&appid=${process.env.OPEN_WEATHER_API_KEY}&units=metric`,
|
||||||
|
};
|
||||||
|
const pollutionData = await axios(config).then((response) => response.data);
|
||||||
|
|
||||||
|
// let temperatureWeight = weather.main.temp;
|
||||||
|
let { sunValue, sunWeight, temperatureWeight } = calculateSun(weather.main.temp);
|
||||||
|
let { humidityValue, humidityWeight } = calculateHumidity(weather.main.humidity);
|
||||||
|
let { pollutionValue, pollutionWeight } = calculatePollution(pollutionData.list[0].main.aqi);
|
||||||
|
let temperature = weather.main.temp;
|
||||||
|
let unit = "°C";
|
||||||
|
if (country.short_name == "GB" || country.short_name == "US") {
|
||||||
|
temperature = (temperature * 9) / 5 + 32;
|
||||||
|
unit = "°F";
|
||||||
|
}
|
||||||
|
let payload = {
|
||||||
|
unit: unit,
|
||||||
|
humidity: humidityValue,
|
||||||
|
temperature: Math.round(temperature),
|
||||||
|
sun: sunValue,
|
||||||
|
pollution: pollutionValue,
|
||||||
|
weights: {
|
||||||
|
Pollution: {
|
||||||
|
value: pollutionWeight,
|
||||||
|
base: 33,
|
||||||
|
},
|
||||||
|
Sun: {
|
||||||
|
value: sunWeight,
|
||||||
|
base: 10,
|
||||||
|
},
|
||||||
|
Temperature: {
|
||||||
|
value: temperatureWeight,
|
||||||
|
base: 0,
|
||||||
|
},
|
||||||
|
Hydration: {
|
||||||
|
value: humidityWeight,
|
||||||
|
base: 15,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return res.status(201).json({
|
||||||
|
success: true,
|
||||||
|
data: payload,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return res.status(500).json({ success: false, message: error.message || "Something went wrong" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function calculateSun(sunTemp) {
|
||||||
|
let maxSun = 56.7;
|
||||||
|
let sun = parseFloat(sunTemp / maxSun) * 100;
|
||||||
|
if (sun > 0 && sun <= 33.334) {
|
||||||
|
return {
|
||||||
|
sunValue: "low",
|
||||||
|
sunWeight: 33.334 * 10,
|
||||||
|
temperatureWeight: 0,
|
||||||
|
};
|
||||||
|
} else if (sun > 33.334 && sun <= 66.667) {
|
||||||
|
return {
|
||||||
|
sunValue: "medium",
|
||||||
|
sunWeight: 66.667 * 10,
|
||||||
|
temperatureWeight: 0,
|
||||||
|
};
|
||||||
|
} else if (sun > 66.667 && sun <= 100) {
|
||||||
|
return {
|
||||||
|
sunValue: "High",
|
||||||
|
sunWeight: 100 * 10,
|
||||||
|
temperatureWeight: 0,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
sunValue: "",
|
||||||
|
sunWeight: 0,
|
||||||
|
temperatureWeight: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function calculateHumidity(humidity) {
|
||||||
|
if (humidity < 30) {
|
||||||
|
return {
|
||||||
|
humidityValue: "Low",
|
||||||
|
humidityWeight: 33.334 * 15,
|
||||||
|
};
|
||||||
|
} else if (humidity >= 30 && humidity < 50) {
|
||||||
|
return {
|
||||||
|
humidityValue: "Medium",
|
||||||
|
humidityWeight: 66.667 * 15,
|
||||||
|
};
|
||||||
|
} else if (humidity >= 50) {
|
||||||
|
return {
|
||||||
|
humidityValue: "High",
|
||||||
|
humidityWeight: 100 * 15,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
humidityValue: "",
|
||||||
|
humidityWeight: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function calculatePollution(airQuality) {
|
||||||
|
// Air Quality Index. Possible values: 1, 2, 3, 4, 5. Where 1 = Good, 2 = Fair, 3 = Moderate, 4 = Poor, 5 = Very Poor.
|
||||||
|
if (airQuality == 1) {
|
||||||
|
return {
|
||||||
|
pollutionValue: "Very low",
|
||||||
|
pollutionWeight: 20 * 33,
|
||||||
|
};
|
||||||
|
} else if (airQuality == 2) {
|
||||||
|
return {
|
||||||
|
pollutionValue: "Low",
|
||||||
|
pollutionWeight: 40 * 33,
|
||||||
|
};
|
||||||
|
} else if (airQuality == 3) {
|
||||||
|
return {
|
||||||
|
pollutionValue: "Moderate",
|
||||||
|
pollutionWeight: 60 * 33,
|
||||||
|
};
|
||||||
|
} else if (airQuality == 4) {
|
||||||
|
return {
|
||||||
|
pollutionValue: "High",
|
||||||
|
pollutionWeight: 80 * 33,
|
||||||
|
};
|
||||||
|
} else if (airQuality == 5) {
|
||||||
|
return {
|
||||||
|
pollutionValue: "Very high",
|
||||||
|
pollutionWeight: 100 * 33,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
pollutionValue: "",
|
||||||
|
pollutionWeight: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = app;
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
const axios = require("axios");
|
||||||
|
|
||||||
|
const app = require("express").Router();
|
||||||
|
|
||||||
|
app.get("/v1/api/get-shopify-products", async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
var config = {
|
||||||
|
method: "get",
|
||||||
|
url: `https://${process.env.SHOPIFY_API_KEY}:${process.env.SHOPIFY_API_PASSWORD}@${process.env.SHOPIFY_SITE}/admin/api/2021-10/products.json`,
|
||||||
|
headers: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await axios(config);
|
||||||
|
return res.status(201).json(response.data);
|
||||||
|
} catch (error) {
|
||||||
|
return res.status(500).json({ success: false, message: error.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
const app = require("express").Router();
|
||||||
|
const db = require("../../models");
|
||||||
|
const crypto = require("crypto");
|
||||||
|
app.post("/v1/api/webhook", async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
const hmac = req.get("X-Shopify-Hmac-Sha256");
|
||||||
|
const rawBody = req.rawBody;
|
||||||
|
if (!verify_webhook(rawBody, hmac)) {
|
||||||
|
return res.sendStatus(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
const webhookId = req.get("X-Shopify-Webhook-Id");
|
||||||
|
const event = req.body;
|
||||||
|
const currentOrderLineItems = event.line_items.map((item) => item.name);
|
||||||
|
|
||||||
|
//this gets the first ever order of said customer since it can't happen unless he goes thro quiz.
|
||||||
|
const customerId = event.customer.id;
|
||||||
|
const customerOrderedBefore = await db.order.findOne({
|
||||||
|
where: {
|
||||||
|
customer_shopify_id: customerId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let attributes = event.note_attributes ?? [];
|
||||||
|
|
||||||
|
if (!attributes.length) {
|
||||||
|
if (!customerOrderedBefore) {
|
||||||
|
return res.sendStatus(204);
|
||||||
|
}
|
||||||
|
attributes.push({
|
||||||
|
name: "answers",
|
||||||
|
value: customerOrderedBefore.answers, //we take old answers
|
||||||
|
});
|
||||||
|
attributes.push({
|
||||||
|
name: "profile",
|
||||||
|
value: customerOrderedBefore.profile, //we take old profile
|
||||||
|
});
|
||||||
|
attributes.push({
|
||||||
|
name: "actives",
|
||||||
|
value: JSON.stringify(currentOrderLineItems ?? []), //we take new actives
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await db.order.getByFields({ webhook_id: webhookId })) return res.sendStatus(205); //webhook handled before
|
||||||
|
|
||||||
|
const orderExists = await db.order.getByFields({ shopify_id: `${event.id}` });
|
||||||
|
const modelParams = {
|
||||||
|
webhook_id: webhookId,
|
||||||
|
shopify_id: event.id,
|
||||||
|
customer_shopify_id: event.customer.id,
|
||||||
|
customer: JSON.stringify(event.customer),
|
||||||
|
answers: attributes.find((attr) => attr.name == "answers")?.value ?? "[]",
|
||||||
|
profile: attributes.find((attr) => attr.name == "profile")?.value ?? "{}",
|
||||||
|
actives: attributes.find((attr) => attr.name == "actives")?.value ?? "[]",
|
||||||
|
items: JSON.stringify(event.line_items ?? []),
|
||||||
|
financial_status: event.financial_status,
|
||||||
|
fulfillment_status: event.fulfillment_status,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (orderExists) {
|
||||||
|
console.log("Modifying order");
|
||||||
|
await db.order.edit(modelParams, orderExists.id);
|
||||||
|
} else {
|
||||||
|
console.log("Creating new order");
|
||||||
|
await db.order.insert(modelParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.sendStatus(200);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return res.sendStatus(500);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
|
|
||||||
|
function verify_webhook(data, hmac_header) {
|
||||||
|
let calculated_hmac = crypto.createHmac("sha256", process.env.SHOPIFY_SECRET_KEY).update(data).digest("base64");
|
||||||
|
return calculated_hmac == hmac_header;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
module.exports = {
|
||||||
|
EMAIL_ADDRESS_NOT_FOUND: 'Email Address Not Found',
|
||||||
|
EMAIL_ADDRESS_ALREADY_EXIST: 'Email Address Already Exists',
|
||||||
|
PASSWORD_NOT_MATCH: 'Password Does Not Match',
|
||||||
|
INVALID_EMAIL_CONFIRMATION_CODE: 'Invalid Email Confirmation Code',
|
||||||
|
INVALID_EMAIL_OR_PASSWORD: 'Invalid Email Or Password',
|
||||||
|
USER_NOT_FOUND: 'User Not Found',
|
||||||
|
};
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const sanitizeHtml = require('sanitize-html');
|
||||||
|
module.exports = {
|
||||||
|
filterEmptyFields(object) {
|
||||||
|
Object.keys(object).forEach((key) => {
|
||||||
|
if (this.empty(object[key])) {
|
||||||
|
delete object[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return object;
|
||||||
|
},
|
||||||
|
empty(value) {
|
||||||
|
return value === '' || value === null || value === undefined;
|
||||||
|
},
|
||||||
|
getMappingKey(mappingFunction, value) {
|
||||||
|
return Object.keys(mappingFunction()).find((key) => mappingFunction()[key].toLowerCase() === value.toLowerCase());
|
||||||
|
},
|
||||||
|
checkFor(requiredFields) {
|
||||||
|
for (const [key, value] of Object.entries(requiredFields)) {
|
||||||
|
if (!value) {
|
||||||
|
throw new Error(`Must provide ${key}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
convertToCents(amount) {
|
||||||
|
return parseFloat(amount) * 100;
|
||||||
|
},
|
||||||
|
convertFromCents(amount) {
|
||||||
|
return parseFloat(amount) / 100;
|
||||||
|
},
|
||||||
|
inject_substitute(text, normalKey, value) {
|
||||||
|
text = text.replace(new RegExp('{{{' + normalKey + '}}}', 'g'), value);
|
||||||
|
return text;
|
||||||
|
},
|
||||||
|
createDirectoriesRecursive(filePath) {
|
||||||
|
let fileDirectoryPath = path.dirname(filePath);
|
||||||
|
if (!fs.existsSync(fileDirectoryPath)) {
|
||||||
|
fs.mkdirSync(fileDirectoryPath, { recursive: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
createDirectoriesRecursiveV2(folderPath) {
|
||||||
|
if (!fs.existsSync(folderPath)) {
|
||||||
|
fs.mkdirSync(folderPath, { recursive: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sanitizeInputs(body) {
|
||||||
|
if (Array.isArray(body)) {
|
||||||
|
body.forEach((item) => {
|
||||||
|
item = sanitizeHtml(item);
|
||||||
|
});
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
if (this.isObject(body)) {
|
||||||
|
Object.keys(body).forEach((key) => {
|
||||||
|
body[key] = sanitizeHtml(body[key]);
|
||||||
|
});
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
return sanitizeHtml(body);
|
||||||
|
},
|
||||||
|
isObject(obj) {
|
||||||
|
return obj === Object(obj);
|
||||||
|
},
|
||||||
|
ucFirst(string) {
|
||||||
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||||
|
},
|
||||||
|
getLocalPath(string) {
|
||||||
|
if (string.includes('\\')) {
|
||||||
|
return string.split('\\public')[1].replace(/\\/g, '/');
|
||||||
|
} else {
|
||||||
|
return string.split('/public')[1];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,313 @@
|
|||||||
|
const { isInteger } = require("lodash");
|
||||||
|
|
||||||
|
module.exports = async function (Table) {
|
||||||
|
Table._primaryKey = function () {
|
||||||
|
return "id";
|
||||||
|
};
|
||||||
|
Table.getLast = async function (parameters) {
|
||||||
|
let where = parameters;
|
||||||
|
if (!where) {
|
||||||
|
where = {};
|
||||||
|
}
|
||||||
|
for (const key in where) {
|
||||||
|
const element = where[key];
|
||||||
|
if (element == undefined || element == null) {
|
||||||
|
delete where.key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = await Table.findAll({
|
||||||
|
limit: 1,
|
||||||
|
where: where,
|
||||||
|
order: [["id", "DESC"]],
|
||||||
|
});
|
||||||
|
return result[0];
|
||||||
|
};
|
||||||
|
Table.getAll = function (parameters, orderBy = Table._primaryKey(), direction = "ASC", orderAssociations, include = []) {
|
||||||
|
let where = parameters;
|
||||||
|
if (!where) {
|
||||||
|
where = {};
|
||||||
|
}
|
||||||
|
for (const key in where) {
|
||||||
|
const element = where[key];
|
||||||
|
if (element == undefined || element == null) {
|
||||||
|
delete where.key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
where: where,
|
||||||
|
include: include,
|
||||||
|
distinct: true,
|
||||||
|
order: [[orderBy, direction]],
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Array.isArray(orderAssociations) && orderAssociations.length > 0) {
|
||||||
|
orderAssociations.forEach(function (order) {
|
||||||
|
params.order[0].unshift(order);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Table.findAll(params);
|
||||||
|
};
|
||||||
|
Table._count = function (parameters, include = []) {
|
||||||
|
let where = parameters;
|
||||||
|
if (!where) {
|
||||||
|
where = {};
|
||||||
|
}
|
||||||
|
for (const key in where) {
|
||||||
|
const element = where[key];
|
||||||
|
if (element == undefined || element == null) {
|
||||||
|
delete where.key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Table._customCountingConditions(where);
|
||||||
|
|
||||||
|
return Table.count({
|
||||||
|
where: where,
|
||||||
|
include: include,
|
||||||
|
distinct: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Table.getPaginated = function (page, limit, parameters, orderBy, direction, orderAssociations = [], include = []) {
|
||||||
|
let where = parameters;
|
||||||
|
|
||||||
|
for (const key in where) {
|
||||||
|
if (where.hasOwnProperty.call(where, key)) {
|
||||||
|
const element = where[key];
|
||||||
|
if (element.length || isInteger(element) || element === Object(element)) {
|
||||||
|
where[key] = element;
|
||||||
|
} else {
|
||||||
|
delete where[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!page) {
|
||||||
|
page = 0;
|
||||||
|
}
|
||||||
|
if (!limit) {
|
||||||
|
limit = 10;
|
||||||
|
}
|
||||||
|
if (!where) {
|
||||||
|
where = {};
|
||||||
|
}
|
||||||
|
if (!orderBy) {
|
||||||
|
orderBy = Table._primaryKey();
|
||||||
|
}
|
||||||
|
if (!direction) {
|
||||||
|
direction = "ASC";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const key in where) {
|
||||||
|
const element = where[key];
|
||||||
|
if (element == undefined || element == null) {
|
||||||
|
delete where.key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let params = {
|
||||||
|
where: where,
|
||||||
|
offset: page * limit,
|
||||||
|
limit: limit,
|
||||||
|
include: include,
|
||||||
|
order: [[orderBy, direction]],
|
||||||
|
distinct: true,
|
||||||
|
};
|
||||||
|
if (Array.isArray(orderAssociations) && orderAssociations.length > 0) {
|
||||||
|
orderAssociations.forEach(function (order) {
|
||||||
|
params.order[0].unshift(order);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Table.findAll(params);
|
||||||
|
};
|
||||||
|
Table.getPaginatedV2 = function (page, limit, parameters, order, direction, include = []) {
|
||||||
|
let where = parameters;
|
||||||
|
|
||||||
|
for (const key in where) {
|
||||||
|
if (where.hasOwnProperty.call(where, key)) {
|
||||||
|
const element = where[key];
|
||||||
|
if (element.length || isInteger(element) || element === Object(element)) {
|
||||||
|
where[key] = element;
|
||||||
|
} else {
|
||||||
|
delete where[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!page) {
|
||||||
|
page = 0;
|
||||||
|
}
|
||||||
|
if (!limit) {
|
||||||
|
limit = 10;
|
||||||
|
}
|
||||||
|
if (!where) {
|
||||||
|
where = {};
|
||||||
|
}
|
||||||
|
if (!order) {
|
||||||
|
order = Table._primaryKey();
|
||||||
|
}
|
||||||
|
if (!direction) {
|
||||||
|
direction = "ASC";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const key in where) {
|
||||||
|
const element = where[key];
|
||||||
|
if (element == undefined || element == null) {
|
||||||
|
delete where.key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let params = {
|
||||||
|
where: where,
|
||||||
|
offset: page * limit,
|
||||||
|
limit: limit,
|
||||||
|
include: include,
|
||||||
|
order: order,
|
||||||
|
distinct: true,
|
||||||
|
};
|
||||||
|
return Table.findAll(params);
|
||||||
|
};
|
||||||
|
Table.getAllByStatus = function (status) {
|
||||||
|
return Table.findAll({
|
||||||
|
where: {
|
||||||
|
status: status,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Table.getByField = function (field, value) {
|
||||||
|
return Table.findOne({
|
||||||
|
where: {
|
||||||
|
[field]: value,
|
||||||
|
},
|
||||||
|
distinct: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Table.getByPK = async function (id, options) {
|
||||||
|
return await Table.findByPk(id, options);
|
||||||
|
};
|
||||||
|
|
||||||
|
Table.getByFields = function (parameters) {
|
||||||
|
let where = parameters;
|
||||||
|
if (!where) {
|
||||||
|
where = {};
|
||||||
|
}
|
||||||
|
for (const key in where) {
|
||||||
|
const element = where[key];
|
||||||
|
if (element == undefined || element == null) {
|
||||||
|
delete where.key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Table.findOne({
|
||||||
|
where: where,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Table.getAllByKeyValue = async function (field, parameters) {
|
||||||
|
let where = parameters;
|
||||||
|
if (!where) {
|
||||||
|
where = {};
|
||||||
|
}
|
||||||
|
let data = [];
|
||||||
|
const results = await Table.findAll({
|
||||||
|
where: where,
|
||||||
|
});
|
||||||
|
|
||||||
|
for (let i = 0; i < results.length; i++) {
|
||||||
|
const element = results[i];
|
||||||
|
let singleField = element[field];
|
||||||
|
data.push({ [element.id]: singleField });
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Table.insert = async function (data, { returnAllFields = false } = {}) {
|
||||||
|
data = Table._preCreateProcessing(data);
|
||||||
|
const insertedRow = await Table.create(Table._filterAllowKeys(data));
|
||||||
|
if (returnAllFields === true) {
|
||||||
|
return insertedRow;
|
||||||
|
}
|
||||||
|
if (insertedRow) {
|
||||||
|
return insertedRow.id;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Table.batchInsert = async function (data) {
|
||||||
|
const insertedRow = await Table.bulkCreate(data, { returning: true });
|
||||||
|
|
||||||
|
if (insertedRow) {
|
||||||
|
return insertedRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Table.edit = async function (data, id) {
|
||||||
|
data = Table._postCreateProcessing(data);
|
||||||
|
const updateRow = await Table.update(Table._filterAllowKeys(data), {
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
}).catch((error) => {
|
||||||
|
throw new Error(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
return updateRow;
|
||||||
|
};
|
||||||
|
|
||||||
|
Table.editByField = async function (data, where) {
|
||||||
|
data = Table._postCreateProcessing(data);
|
||||||
|
|
||||||
|
const updateRow = await Table.update(Table._filterAllowKeys(data), {
|
||||||
|
where,
|
||||||
|
});
|
||||||
|
|
||||||
|
return updateRow;
|
||||||
|
};
|
||||||
|
|
||||||
|
Table.delete = async function (id) {
|
||||||
|
const updateRow = await Table.update(
|
||||||
|
{
|
||||||
|
status: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return updateRow;
|
||||||
|
};
|
||||||
|
|
||||||
|
Table.realDelete = async function (id) {
|
||||||
|
return Table.destroy({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Table.realDeleteByFields = async function (parameters, id) {
|
||||||
|
let where = parameters;
|
||||||
|
if (!where) {
|
||||||
|
where = {
|
||||||
|
id: id,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
where["id"] = id;
|
||||||
|
}
|
||||||
|
return Table.destroy({
|
||||||
|
where: where,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Table.realDeleteByUniqueField = async function (field, value) {
|
||||||
|
let where = {};
|
||||||
|
where[field] = value;
|
||||||
|
return Table.destroy({
|
||||||
|
where: where,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
exports.validateEmail = (email) => {
|
||||||
|
const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||||
|
|
||||||
|
const reStartAndEnd = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}/g;
|
||||||
|
|
||||||
|
if (re.test(email) && reStartAndEnd.test(email)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
'use strict';
|
||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*/
|
||||||
|
|
||||||
|
const archiver = require('archiver');
|
||||||
|
const AWS = require('aws-sdk');
|
||||||
|
const s3 = new AWS.S3();
|
||||||
|
const stream = require('stream');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
AWS.config.update({
|
||||||
|
accessKeyId: process.env.DYNAMIC_CONFIG_AWS_KEY,
|
||||||
|
secretAccessKey: process.env.DYNAMIC_CONFIG_AWS_SECRET,
|
||||||
|
region: process.env.DYNAMIC_CONFIG_AWS_REGION,
|
||||||
|
});
|
||||||
|
|
||||||
|
const main = async () => {
|
||||||
|
const archive = archiver('zip', {
|
||||||
|
zlib: { level: 9 }, // Sets the compression level.
|
||||||
|
});
|
||||||
|
|
||||||
|
archive.directory(path.join(__dirname, '../../', '/uploads'), false);
|
||||||
|
|
||||||
|
const uploadStream = new stream.PassThrough();
|
||||||
|
archive.pipe(uploadStream);
|
||||||
|
archive.finalize();
|
||||||
|
|
||||||
|
archive.on('warning', function (err) {
|
||||||
|
if (err.code === 'ENOENT') {
|
||||||
|
console.log(err);
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
archive.on('error', function (err) {
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
|
||||||
|
archive.on('end', function () {
|
||||||
|
console.log('archive end');
|
||||||
|
});
|
||||||
|
|
||||||
|
await uploadFromStream(uploadStream);
|
||||||
|
console.log('all done');
|
||||||
|
};
|
||||||
|
|
||||||
|
const uploadFromStream = async (pass) => {
|
||||||
|
const s3params = {
|
||||||
|
Bucket: process.env.DYNAMIC_CONFIG_AWS_BUCKET,
|
||||||
|
Key: `uploads.zip`,
|
||||||
|
Body: pass,
|
||||||
|
ContentType: 'application/zip',
|
||||||
|
};
|
||||||
|
return s3.upload(s3params).promise();
|
||||||
|
};
|
||||||
|
|
||||||
|
main();
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
'use strict';
|
||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*/
|
||||||
|
|
||||||
|
const AWS = require('aws-sdk');
|
||||||
|
const S3 = new AWS.S3();
|
||||||
|
|
||||||
|
const db = require('../models');
|
||||||
|
|
||||||
|
AWS.config.update({
|
||||||
|
accessKeyId: process.env.DYNAMIC_CONFIG_AWS_KEY,
|
||||||
|
secretAccessKey: process.env.DYNAMIC_CONFIG_AWS_SECRET,
|
||||||
|
region: process.env.DYNAMIC_CONFIG_AWS_REGION,
|
||||||
|
});
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
/** @type {Array.<{url: string}>} */
|
||||||
|
const images = await db.image.getAllByStatus(0);
|
||||||
|
|
||||||
|
const mapKeys = images.map(({ url }) => {
|
||||||
|
// TODO: DO MAPPING
|
||||||
|
return url;
|
||||||
|
});
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
Bucket: process.env.AWS_S3_BUCKET,
|
||||||
|
Delete: { Objects: mapKeys },
|
||||||
|
};
|
||||||
|
|
||||||
|
S3.deleteObjects(params, (error, data) => {
|
||||||
|
if (error) console.log(error);
|
||||||
|
else console.log(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
'use strict';
|
||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*/
|
||||||
|
|
||||||
|
const db = require('../models');
|
||||||
|
|
||||||
|
(async function tokenCronJob() {
|
||||||
|
await db.query('UPDATE `token` SET status=0 WHERE `expire_at` < NOW();');
|
||||||
|
await db.query('DELETE FROM `token` WHERE status=0;');
|
||||||
|
})();
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { nanoid} = require('nanoid');
|
||||||
|
|
||||||
|
const SessionService = require('../../services/SessionService');
|
||||||
|
const uploader = require('../../tools/file/uploader');
|
||||||
|
const db = require('../../models');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
initializeApi: function (app) {
|
||||||
|
app.post(
|
||||||
|
"/api/replace-this",
|
||||||
|
SessionService.verifySessionMiddleware(role),
|
||||||
|
async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
const imageUploadModel = require("../view_models/image_upload_local.js")
|
||||||
|
|
||||||
|
const viewModel = imageUploadModel(db.image)
|
||||||
|
|
||||||
|
|
||||||
|
const url = await viewModel.upload_resource(req, rest);
|
||||||
|
await viewModel.create_resource({ url });
|
||||||
|
|
||||||
|
return res.status(201).json({success:true, message:"xyzimage_uploaded_successfully"});
|
||||||
|
} catch (error) {
|
||||||
|
return res.status(500).json({success:false, message:"xyzsomething_went_wrong"})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
app.post(
|
||||||
|
"/api/replace-this",
|
||||||
|
SessionService.verifySessionMiddleware(role),
|
||||||
|
async function (req, res, next) {
|
||||||
|
try {
|
||||||
|
const fileUploadModel = require("../view_models/file_upload_local.js")
|
||||||
|
|
||||||
|
const viewModel = fileUploadModel(db.image)
|
||||||
|
|
||||||
|
|
||||||
|
const url = await viewModel.upload_resource(req, rest);
|
||||||
|
await viewModel.create_resource({ url });
|
||||||
|
|
||||||
|
return res.status(201).json({success:true, message:"xyzimage_uploaded_successfully"});
|
||||||
|
} catch (error) {
|
||||||
|
return res.status(500).json({success:false, message:"xyzsomething_went_wrong"})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return app;
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
"use strict";
|
||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2020*/
|
||||||
|
/**
|
||||||
|
* Lambda
|
||||||
|
* @copyright 2020 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const awsServerlessExpress = require("aws-serverless-express");
|
||||||
|
const app = require("./app");
|
||||||
|
const server = awsServerlessExpress.createServer(app);
|
||||||
|
exports.handler = (event, context) => {
|
||||||
|
context.callbackWaitsForEmptyEventLoop = false;
|
||||||
|
awsServerlessExpress.proxy(server, event, context);
|
||||||
|
};
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
const models = require('./models');
|
||||||
|
models.sequelize.sync({ force: false, alter: true }).then(function () {});
|
||||||
@@ -0,0 +1,695 @@
|
|||||||
|
-- --------------------------------------------------------
|
||||||
|
-- Host: 127.0.0.1
|
||||||
|
-- Server version: 10.4.22-MariaDB - mariadb.org binary distribution
|
||||||
|
-- Server OS: Win64
|
||||||
|
-- HeidiSQL Version: 11.3.0.6295
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET NAMES utf8 */;
|
||||||
|
/*!50503 SET NAMES utf8mb4 */;
|
||||||
|
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||||
|
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||||
|
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||||
|
|
||||||
|
|
||||||
|
-- Dumping database structure for mkd
|
||||||
|
DROP DATABASE IF EXISTS `mkd`;
|
||||||
|
CREATE DATABASE IF NOT EXISTS `mkd` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
|
||||||
|
USE `mkd`;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.active
|
||||||
|
DROP TABLE IF EXISTS `active`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `active` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` varchar(255) DEFAULT NULL,
|
||||||
|
`handle` text DEFAULT NULL,
|
||||||
|
`description` text DEFAULT NULL,
|
||||||
|
`variables_scores` text DEFAULT NULL,
|
||||||
|
`cart_limit` int(11) DEFAULT 1,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.active: ~26 rows (approximately)
|
||||||
|
DELETE FROM `active`;
|
||||||
|
INSERT INTO `active` (`id`, `name`, `variables_scores`, `created_at`, `updated_at`, `handle`, `description`, `cart_limit`) VALUES
|
||||||
|
(1, 'Acai', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"70","Hydration":"70","Breakouts":"","Color":"","Sun":"90","Hyperpigmentation":"50","Hypopigmentation":"","Redness":"90","Lines":"80","Firmness":"90","Pores":"20","Blackheads":"10","Allergies":"","Pollution":"70","Temperature":"","Stress":"70","Diet":"","Sleep":"20","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-08-04 15:20:34', NULL, ' ', 1),
|
||||||
|
(2, 'Bakuchiol', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"80","Hydration":"0","Breakouts":"100","Color":"","Sun":"100","Hyperpigmentation":"100","Hypopigmentation":"","Redness":"90","Lines":"90","Firmness":"100","Pores":"50","Blackheads":"80","Allergies":"","Pollution":"0","Temperature":"","Stress":"0","Diet":"","Sleep":"80","Blue Light":"","Oxygenation":"80"}', '2021-12-28 17:18:43', '2022-03-11 18:41:01', NULL, NULL, 1),
|
||||||
|
(3, 'Base', NULL, '2021-12-28 17:18:43', '2022-03-11 18:41:01', NULL, NULL, 1),
|
||||||
|
(4, 'Base Refill', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"","Hydration":"","Breakouts":"","Color":"","Sun":"","Hyperpigmentation":"","Hypopigmentation":"","Redness":"","Lines":"","Firmness":"","Pores":"","Blackheads":"","Allergies":"","Pollution":"","Temperature":"","Stress":"","Diet":"","Sleep":"","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-08-04 16:29:41', NULL, ' ', 1),
|
||||||
|
(5, 'Chamomile', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"100","Hydration":"10","Breakouts":"70","Color":"","Sun":"90","Hyperpigmentation":"70","Hypopigmentation":"","Redness":"100","Lines":"50","Firmness":"50","Pores":"70","Blackheads":"50","Allergies":"","Pollution":"70","Temperature":"","Stress":"40","Diet":"","Sleep":"30","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-11 18:41:01', NULL, NULL, 1),
|
||||||
|
(6, 'Chia', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"90","Hydration":"70","Breakouts":"100","Color":"","Sun":"90","Hyperpigmentation":"70","Hypopigmentation":"","Redness":"20","Lines":"50","Firmness":"40","Pores":"80","Blackheads":"100","Allergies":"","Pollution":"50","Temperature":"","Stress":"10","Diet":"","Sleep":"50","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-11 18:41:01', NULL, NULL, 1),
|
||||||
|
(7, 'Coconut', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"80","Hydration":"100","Breakouts":"30","Color":"","Sun":"90","Hyperpigmentation":"20","Hypopigmentation":"","Redness":"70","Lines":"30","Firmness":"40","Pores":"20","Blackheads":"0","Allergies":"","Pollution":"80","Temperature":"","Stress":"10","Diet":"","Sleep":"50","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-11 18:41:01', NULL, NULL, 1),
|
||||||
|
(8, 'Cogon Grass', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"40","Hydration":"100","Breakouts":"20","Color":"","Sun":"90","Hyperpigmentation":"40","Hypopigmentation":"","Redness":"10","Lines":"70","Firmness":"80","Pores":"20","Blackheads":"10","Allergies":"","Pollution":"10","Temperature":"","Stress":"10","Diet":"","Sleep":"50","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-11 18:41:01', NULL, NULL, 1),
|
||||||
|
(9, 'Cucumber', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"80","Hydration":"100","Breakouts":"60","Color":"","Sun":"90","Hyperpigmentation":"20","Hypopigmentation":"","Redness":"80","Lines":"50","Firmness":"60","Pores":"50","Blackheads":"20","Allergies":"","Pollution":"40","Temperature":"","Stress":"10","Diet":"","Sleep":"50","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-11 18:41:01', NULL, NULL, 1),
|
||||||
|
(10, 'Dragon\'s Blood', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"80","Hydration":"80","Breakouts":"70","Color":"","Sun":"90","Hyperpigmentation":"50","Hypopigmentation":"","Redness":"80","Lines":"90","Firmness":"100","Pores":"20","Blackheads":"20","Allergies":"","Pollution":"80","Temperature":"","Stress":"80","Diet":"","Sleep":"50","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-11 18:41:01', NULL, NULL, 1),
|
||||||
|
(11, 'Ginseng', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"80","Hydration":"10","Breakouts":"30","Color":"","Sun":"100","Hyperpigmentation":"50","Hypopigmentation":"","Redness":"70","Lines":"90","Firmness":"100","Pores":"10","Blackheads":"10","Allergies":"","Pollution":"90","Temperature":"","Stress":"10","Diet":"","Sleep":"20","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-11 18:41:01', NULL, ' ', 1),
|
||||||
|
(12, 'Gotu Kola', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"90","Hydration":"80","Breakouts":"60","Color":"","Sun":"90","Hyperpigmentation":"60","Hypopigmentation":"","Redness":"90","Lines":"60","Firmness":"70","Pores":"60","Blackheads":"20","Allergies":"","Pollution":"70","Temperature":"","Stress":"10","Diet":"","Sleep":"50","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-11 18:41:01', NULL, NULL, 1),
|
||||||
|
(13, 'Licorice Root', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"0","Hydration":"100","Breakouts":"10","Color":"","Sun":"40","Hyperpigmentation":"100","Hypopigmentation":"","Redness":"90","Lines":"50","Firmness":"20","Pores":"10","Blackheads":"10","Allergies":"","Pollution":"30","Temperature":"","Stress":"10","Diet":"","Sleep":"70","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-11 18:41:01', NULL, ' ', 1),
|
||||||
|
(14, 'Moringa', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"90","Hydration":"100","Breakouts":"30","Color":"","Sun":"90","Hyperpigmentation":"80","Hypopigmentation":"","Redness":"70","Lines":"70","Firmness":"80","Pores":"30","Blackheads":"30","Allergies":"","Pollution":"80","Temperature":"","Stress":"10","Diet":"","Sleep":"50","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-11 18:41:02', NULL, NULL, 1),
|
||||||
|
(15, 'Moth Bean', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"90","Hydration":"10","Breakouts":"90","Color":"","Sun":"30","Hyperpigmentation":"90","Hypopigmentation":"","Redness":"10","Lines":"90","Firmness":"100","Pores":"80","Blackheads":"90","Allergies":"","Pollution":"50","Temperature":"","Stress":"10","Diet":"","Sleep":"80","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-11 18:41:02', NULL, NULL, 1),
|
||||||
|
(17, 'Colloidal Oat', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"100","Hydration":"100","Breakouts":"10","Color":"","Sun":"100","Hyperpigmentation":"","Hypopigmentation":"","Redness":"70","Lines":"30","Firmness":"40","Pores":"10","Blackheads":"0","Allergies":"","Pollution":"90","Temperature":"","Stress":"10","Diet":"","Sleep":"","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-11 18:41:01', NULL, ' ', 1),
|
||||||
|
(18, 'Okra Extract', '{"Bio Age":"","Age":"80","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"80","Hydration":"0","Breakouts":"40","Color":"","Sun":"90","Hyperpigmentation":"","Hypopigmentation":"","Redness":"40","Lines":"200","Firmness":"100","Pores":"","Blackheads":"10","Allergies":"","Pollution":"80","Temperature":"","Stress":"0","Diet":"","Sleep":"20","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-22 19:07:54', NULL, ' ', 1),
|
||||||
|
(19, 'Olive Squalane', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"100","Hydration":"100","Breakouts":"10","Color":"","Sun":"90","Hyperpigmentation":"0","Hypopigmentation":"","Redness":"80","Lines":"30","Firmness":"40","Pores":"10","Blackheads":"0","Allergies":"","Pollution":"60","Temperature":"","Stress":"10","Diet":"","Sleep":"50","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-11 18:41:02', NULL, NULL, 1),
|
||||||
|
(20, 'Red Raddish', NULL, '2021-12-28 17:18:43', '2022-03-11 18:41:02', NULL, NULL, 1),
|
||||||
|
(21, 'Rose Hip', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"30","Hydration":"100","Breakouts":"40","Color":"","Sun":"90","Hyperpigmentation":"50","Hypopigmentation":"","Redness":"60","Lines":"80","Firmness":"90","Pores":"20","Blackheads":"10","Allergies":"","Pollution":"70","Temperature":"","Stress":"70","Diet":"","Sleep":"50","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-11 18:41:02', NULL, NULL, 1),
|
||||||
|
(22, 'Sake Extract', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"90","Hydration":"100","Breakouts":"10","Color":"","Sun":"90","Hyperpigmentation":"70","Hypopigmentation":"","Redness":"30","Lines":"80","Firmness":"90","Pores":"10","Blackheads":"10","Allergies":"","Pollution":"10","Temperature":"","Stress":"10","Diet":"","Sleep":"50","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-11 18:41:02', NULL, NULL, 1),
|
||||||
|
(23, 'Sandalwood', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"90","Hydration":"60","Breakouts":"40","Color":"","Sun":"90","Hyperpigmentation":"60","Hypopigmentation":"","Redness":"100","Lines":"50","Firmness":"60","Pores":"30","Blackheads":"30","Allergies":"","Pollution":"60","Temperature":"","Stress":"10","Diet":"","Sleep":"40","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-11 18:41:02', NULL, NULL, 1),
|
||||||
|
(24, 'Tonka Bean', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"70","Hydration":"70","Breakouts":"50","Color":"","Sun":"120","Hyperpigmentation":"10","Hypopigmentation":"","Redness":"10","Lines":"80","Firmness":"100","Pores":"20","Blackheads":"10","Allergies":"","Pollution":"80","Temperature":"","Stress":"10","Diet":"","Sleep":"","Blue Light":"40","Oxygenation":""}', '2021-12-28 17:18:43', '2022-07-12 13:47:38', NULL, ' ', 1),
|
||||||
|
(25, 'White Willow Bark', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"70","Hydration":"0","Breakouts":"100","Color":"","Sun":"20","Hyperpigmentation":"90","Hypopigmentation":"","Redness":"80","Lines":"80","Firmness":"70","Pores":"80","Blackheads":"100","Allergies":"","Pollution":"40","Temperature":"","Stress":"10","Diet":"","Sleep":"100","Blue Light":"","Oxygenation":""}', '2021-12-28 17:18:43', '2022-03-11 18:41:02', NULL, NULL, 1),
|
||||||
|
(28, 'Yeast Extract (Collagen)', '{"Bio Age":"","Age":"","Gender":"","Pregnancy":"","Hair":"","Sensitivity":"30","Hydration":"80","Breakouts":"","Color":"","Sun":"90","Hyperpigmentation":"20","Hypopigmentation":"","Redness":"20","Lines":"90","Firmness":"100","Pores":"70","Blackheads":"","Allergies":"","Pollution":"50","Temperature":"","Stress":"10","Diet":"","Sleep":"50","Blue Light":"","Oxygenation":""}', '2022-01-07 12:05:01', '2022-03-11 18:41:02', NULL, NULL, 1),
|
||||||
|
(29, 'Mushrooms', NULL, '2022-02-21 22:39:59', '2022-03-11 18:41:02', NULL, NULL, 1);
|
||||||
|
/*!40000 ALTER TABLE `active` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.activity_log
|
||||||
|
DROP TABLE IF EXISTS `activity_log`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `activity_log` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` varchar(255) DEFAULT NULL,
|
||||||
|
`action` varchar(255) DEFAULT NULL,
|
||||||
|
`data` text DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.activity_log: ~0 rows (approximately)
|
||||||
|
DELETE FROM `activity_log`;
|
||||||
|
/*!40000 ALTER TABLE `activity_log` DISABLE KEYS */;
|
||||||
|
/*!40000 ALTER TABLE `activity_log` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.admin_operation
|
||||||
|
DROP TABLE IF EXISTS `admin_operation`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `admin_operation` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`user_id` int(11) DEFAULT NULL,
|
||||||
|
`action` varchar(255) DEFAULT NULL,
|
||||||
|
`detail` text DEFAULT NULL,
|
||||||
|
`last_ip` varchar(255) DEFAULT NULL,
|
||||||
|
`user_agent` varchar(255) DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.admin_operation: ~0 rows (approximately)
|
||||||
|
DELETE FROM `admin_operation`;
|
||||||
|
/*!40000 ALTER TABLE `admin_operation` DISABLE KEYS */;
|
||||||
|
/*!40000 ALTER TABLE `admin_operation` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.answer
|
||||||
|
DROP TABLE IF EXISTS `answer`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `answer` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`question_id` int(11) DEFAULT NULL,
|
||||||
|
`order` int(11) DEFAULT NULL,
|
||||||
|
`answer` text DEFAULT NULL,
|
||||||
|
`answer_value` float DEFAULT NULL,
|
||||||
|
`hide_answer` tinyint(1) DEFAULT NULL,
|
||||||
|
`explaination` text DEFAULT NULL,
|
||||||
|
`image_id` text DEFAULT NULL,
|
||||||
|
`response_header` text DEFAULT NULL,
|
||||||
|
`response_body` text DEFAULT NULL,
|
||||||
|
`response_arguments` text DEFAULT NULL,
|
||||||
|
`black_list_actives` text DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=97 DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.answer: ~96 rows (approximately)
|
||||||
|
DELETE FROM `answer`;
|
||||||
|
/*!40000 ALTER TABLE `answer` DISABLE KEYS */;
|
||||||
|
INSERT INTO `answer` (`id`, `question_id`, `order`, `answer`, `answer_value`, `hide_answer`, `explaination`, `image_id`, `response_header`, `response_body`, `response_arguments`, `black_list_actives`, `created_at`, `updated_at`) VALUES
|
||||||
|
(1, 1, 1, NULL, NULL, NULL, NULL, NULL, '<<<name>>>', NULL, '["name"]', NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(2, 2, 1, '<25', NULL, NULL, NULL, NULL, NULL, 'We will focus on actives that will improving your skin health and appearance without adding anything unnecessary.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(3, 2, 2, '25-40', NULL, NULL, NULL, NULL, NULL, 'We will create a custom formula containing actives to ensure we maintain your optimal skin health and appearance. We will spoil you with some wonderful actives that will help delay visible signs of skin aging.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(4, 2, 3, '>40', NULL, NULL, NULL, NULL, NULL, 'We have so many luxurious actives that will work to address any of the desires that come with time and knowledge.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(5, 3, 1, 'Female', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(6, 3, 2, 'Male', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(7, 3, 3, 'Non-binary', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(8, 3, 4, 'Other', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(9, 4, 1, 'Yes', 100, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(10, 4, 2, 'No', 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(11, 5, 1, 'Beard', 100, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(12, 5, 2, 'Stubble', 66, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(13, 5, 3, 'Clean', 33, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(14, 5, 4, 'Shaven', 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(15, 6, 1, 'It\'s not', NULL, NULL, NULL, '2', 'Wonderful!', 'We can now eliminate many active ingredients that are just suited for sensitive skin and focus on just the wonderful actives that will perform other wonderful functions! Don’t worry we won’t be adding anything that can or will lead to extra sensitivity.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(16, 6, 2, 'Moderately', NULL, NULL, NULL, '3', 'Noted.', 'We have many wonderful ingredients that are specifically proven to be soothing even for mildly sensitive skin. We will add these along with other functional actives that are non-sensitizing.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(17, 6, 3, 'Extremely', NULL, NULL, NULL, '4', 'Noted.', 'We have many wonderful ingredients that are specifically proven to be soothing for sensitive skin. We will add these along with other functional actives that are non-sensitizing.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(18, 7, 1, 'Very Dry', NULL, NULL, NULL, '5', 'Let’s hydrate!', 'We will add some wonderful hydrating actives that will specifically address your dry skin needs (some of the later questions will help us determine exactly which of our hydrating actives are perfect for you based on their scientific mode of action)', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(19, 7, 2, 'Normal / Combination', NULL, NULL, NULL, '6', 'We know the feeling!', 'We have some wonderful ingredients that will maintain optimal skin hydration while controlling excess oil production.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(20, 7, 3, 'Very Oily', NULL, NULL, NULL, '7', 'Ok! We’ll balance that out.', 'We will make sure to add actives that will help control excess skin oiliness, while still addressing all your other skin needs.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(21, 8, 1, 'Hardly', NULL, NULL, NULL, NULL, 'Great!', 'We will now just focus on those actives you need', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(22, 8, 2, 'Sometimes', NULL, NULL, NULL, NULL, 'Great!', 'We\'ll make sure not to add any actives that may lead to breakouts in breakout-prone skin', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(23, 8, 3, 'Always', NULL, NULL, NULL, NULL, 'Noted.', 'We will add some of our amazing oil-control actives to alleviate some of the factors that can aggravate breakout prone skin. (Note: due to the personalized nature of our system we cannot make any claims to treat or prevent acne in accordance with FDA regulations.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(24, 9, 1, '15', 100, NULL, NULL, '8', NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(25, 9, 2, '14', 93.3333, NULL, NULL, '9', NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(26, 9, 3, '13', 86.6667, NULL, NULL, '10', NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(27, 9, 4, '12', 80, NULL, NULL, '11', NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(28, 9, 5, '11', 73.3333, NULL, NULL, '12', NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(29, 9, 6, '10', 66.6667, NULL, NULL, '13', NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(30, 9, 7, '9', 60, NULL, NULL, '14', NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(31, 9, 8, '8', 53.3333, NULL, NULL, '15', NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(32, 9, 9, '7', 46.6667, NULL, NULL, '16', NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(33, 9, 10, '6', 40, NULL, NULL, '17', NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(34, 9, 11, '5', 33.3333, NULL, NULL, '18', NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(35, 9, 12, '4', 26.6667, NULL, NULL, '19', NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(36, 9, 13, '3', 20, NULL, NULL, '20', NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(37, 9, 14, '2', 13.3333, NULL, NULL, '21', NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(38, 9, 15, '1', 6.66667, NULL, NULL, '22', NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(39, 10, 1, 'Never', NULL, NULL, NULL, NULL, NULL, 'Keep the sunscreen close! We’ll make sure to add some wonderful actives that will help you with your beautiful glow', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(40, 10, 2, 'Sometimes', NULL, NULL, NULL, NULL, NULL, 'Don’t forget the sunscreen! We’ll make sure to add some wonderful actives that will help you with your beautiful glow', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(41, 10, 3, 'Always', NULL, NULL, NULL, NULL, NULL, 'We’ll make sure to add some wonderful actives that will help you with your beautiful glow.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(42, 11, 2, 'Yes', NULL, NULL, NULL, NULL, NULL, 'We’ll add some of our wonderful actives that will minimize the appearance of any hyper or hypo-pigmentation.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(43, 11, 1, 'No', NULL, NULL, NULL, NULL, NULL, 'Great, we can eliminate the addition of unnecessary actives and only focus on those that you need.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(44, 12, 3, 'Instant Burn', NULL, NULL, NULL, NULL, 'We hear your pain!', 'Make sure to wear proper SPF and we’ll make sure we add actives that are not sun-sensitizing.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(45, 12, 2, 'Middle', NULL, NULL, NULL, NULL, 'Noted.', 'Make sure to wear proper SPF and we’ll make sure we add actives that will not make your skin extra sensitive to the sun during the day.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(46, 12, 1, 'Hardly ever', NULL, NULL, NULL, NULL, 'Lucky!', 'We can focus on all the great actives your skin needs without the sun’s distraction – though we still recommend using a daily SPF.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(47, 13, 1, 'Red? Huh? No red here', NULL, NULL, NULL, '23', 'Great!', 'We’ll just focus on the actives that you need.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(48, 13, 2, 'Occaisonally red & blotchy.', NULL, NULL, NULL, '24', 'Noted.', 'We have amazing actives specifically for redness – keep going till the end to find out what we have chosen specifically for your needs.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(49, 13, 3, 'I am constantly seeing red', NULL, NULL, NULL, '24', 'Noted.', 'We have amazing actives specifically for redness – keep going till the end to find out what we have chosen specifically for your needs.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(50, 15, 1, 'No Wrinkles/Lines', NULL, NULL, NULL, '25', 'Amazing <<<name>>>,', 'We have some amazing anti-wrinkle actives, most with more than ten letters, and you don’t need any of them. Save your money to splurge on things that will actually do something for you.', '["name"]', NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(51, 15, 2, 'A Few Lines', NULL, 1, NULL, '26', NULL, 'We have some wonderful actives that will minimize the appearance of lines. We’ll just focus on those that will give you the best bang for your buck.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(52, 15, 3, 'A Few Lines Observable at all times', NULL, 1, NULL, '27', NULL, 'We have some wonderful actives that will minimize the appearance of lines. We’ll just focus on those that will give you the best bang for your buck.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(53, 15, 4, 'Some Lines', NULL, NULL, NULL, '28', NULL, 'We have some wonderful actives that will minimize the appearance of lines. We’ll just focus on those that will give you the best bang for your buck.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(54, 15, 5, 'Lines Plus Hints of Wrinkles', NULL, 1, NULL, '29', NULL, 'We have some wonderful actives that will minimize the appearance of lines. We’ll just focus on those that will give you the best bang for your buck.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(55, 15, 6, 'A Few Wrinkles', NULL, 1, NULL, '30', 'We’re going to add some of our luxurious anti-wrinkle actives. Keep going till the end to see what we recommend.', NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(56, 15, 7, 'Lots of Wrinkles', NULL, NULL, NULL, '31', 'We’re going to add some of our luxurious anti-wrinkle actives. Keep going till the end to see what we recommend.', NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(57, 16, 1, 'Firm as a baby', NULL, NULL, NULL, NULL, 'Amazing!!', 'We’ll focus on the actives more appropriate to your skin and ensure we maintain your skin’s natural resilience.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(58, 16, 2, 'Middle', NULL, NULL, NULL, NULL, NULL, 'We’ll add some luxurious actives to your formulation that will help prevent and improve your skins firmness.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(59, 16, 3, 'Sagging', NULL, NULL, NULL, NULL, 'We got you!', 'We’ll add some of our wonderful actives that will improve your skin’s appearance of firmness.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(60, 17, 1, 'No - smooth as can be', NULL, NULL, NULL, NULL, 'Lucky you!', 'We can eliminate actives that will just be extra clutter for your wonderful skin.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(61, 17, 2, 'Some', NULL, NULL, NULL, NULL, NULL, 'We’ll keep this in mind (our algorithm’s mind) as we create your perfect formula.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(62, 17, 3, 'A lot', NULL, NULL, NULL, NULL, NULL, 'We’ll keep this in mind (our algorithm’s mind) as we create your perfect formula.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(63, 18, 1, 'No', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(64, 18, 2, 'Some', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(65, 18, 3, 'A lot', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(66, 19, 1, 'Yes', 100, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(67, 19, 2, 'No', 0, NULL, NULL, NULL, 'Lucky You!', NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(68, 20, 1, 'Banana', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(69, 20, 2, 'Olive', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(70, 20, 3, 'Sunflowers', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(71, 22, 1, 'Never', NULL, NULL, NULL, NULL, 'Great!', 'This means your skin is exposed to less pollution and better oxygenation!', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(72, 22, 2, 'Sometimes', NULL, NULL, NULL, NULL, NULL, 'We’ll make sure to add extra actives to address the pollution your skin is exposed to.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(73, 22, 3, 'Multiple per day', NULL, NULL, NULL, NULL, 'Got it.', 'Your formula will include actives for anti-pollution and increased oxygenation to your skin.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(74, 23, 1, 'Cool as a cucumber', NULL, NULL, NULL, NULL, 'Lucky you!', 'We’ll rather focus on areas that are of greater concern to you.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(75, 23, 2, 'Sometimes', NULL, NULL, NULL, NULL, NULL, 'Occasional stress can release cortisol and other factors that can negatively affect the skin. We’ll add some adaptogens and other actives that can help mitigate some of these effects.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(76, 23, 3, 'In a constant state of anxiety', NULL, NULL, NULL, NULL, NULL, 'Stress can release cortisol and other factors that can negatively affect the skin. We’ll add some adaptogens and other actives that can help mitigate some of these effects.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(77, 24, 1, 'Vegan/Vegetarian', 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(78, 24, 2, 'Flexitarian, I sometime eat meat', 25, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(79, 24, 3, 'Pescatarian, I’ll have fish and seafood, but no meat', 50, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(80, 24, 4, 'I stay away from red meat', 75, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(81, 24, 5, 'I eat everything', 100, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(82, 25, 1, '<4', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(83, 25, 2, '5-7', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(84, 25, 3, '8+', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(85, 26, 1, '0-2', NULL, NULL, NULL, NULL, 'Good for you!', 'Blue light emitted from screens can be harmful to your skin’s health and appearance. Your low exposure means we can rather focus on other areas to optimize your skin health and appearance.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(86, 26, 2, '2-6', NULL, NULL, NULL, NULL, NULL, 'Blue light emitted from screens can be harmful to your skin’s health and appearance. No worries though, we’ll add some actives, such as our innovative Rockrose extract that will help mitigate some of these effects.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(87, 26, 3, '6+', NULL, NULL, NULL, NULL, NULL, 'Blue light emitted from screens can affect your skin’s circadian rhythm as well as affect your skin’s health and appearance. We’ll add some actives, such as our innovative Rockrose extract that will help mitigate some of these effect', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(88, 27, 1, '0', NULL, NULL, NULL, '32', NULL, 'We’ll add extra hydrating actives, but we recommend you drink more so your skin gets nourished from within as well.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(89, 27, 2, '4', NULL, NULL, NULL, '33', NULL, 'We’ll add extra hydrating actives, but we recommend you drink more so your skin gets nourished from within as well.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(90, 27, 3, '8+', NULL, NULL, NULL, '34', 'Great!', 'You don’t need extra actives to compensate from a lack of internal hydration.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(91, 28, 1, 'None', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(92, 28, 2, 'Full Coverage', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(93, 29, 1, 'Low', NULL, NULL, NULL, NULL, NULL, 'We’ll add extra actives to give your skin an extra boost on oxygenation and nutrient delivery.', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(94, 29, 2, 'High', NULL, NULL, NULL, NULL, 'Great!', 'By exercising you are providing extra oxygenation and nutrient delivery to your skin, so we don’t have to add extra actives to do what you are already doing an even better job at. ', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(95, 30, 1, 'No', NULL, 0, NULL, NULL, 'Great!', 'We can eliminate the addition of unnecessary actives and only focus on those that you need. ', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(96, 30, 1, 'Yes', NULL, 0, NULL, NULL, NULL, 'We\'ll add some of our wonderful actives that will minimize the appearance of hypopigmentation over time', NULL, NULL, '2022-04-10 11:07:44', '2022-04-10 11:07:44');
|
||||||
|
/*!40000 ALTER TABLE `answer` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.configuration
|
||||||
|
DROP TABLE IF EXISTS `configuration`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `configuration` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`image_id` int(11) DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.configuration: ~1 rows (approximately)
|
||||||
|
DELETE FROM `configuration`;
|
||||||
|
/*!40000 ALTER TABLE `configuration` DISABLE KEYS */;
|
||||||
|
INSERT INTO `configuration` (`id`, `image_id`, `created_at`, `updated_at`) VALUES
|
||||||
|
(1, 35, '2022-04-10 11:07:43', '2022-04-10 11:07:43');
|
||||||
|
/*!40000 ALTER TABLE `configuration` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.credential
|
||||||
|
DROP TABLE IF EXISTS `credential`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `credential` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`oauth` varchar(255) DEFAULT NULL,
|
||||||
|
`email` varchar(255) DEFAULT NULL,
|
||||||
|
`password` varchar(255) DEFAULT NULL,
|
||||||
|
`user_id` int(11) DEFAULT NULL,
|
||||||
|
`type` int(11) DEFAULT NULL,
|
||||||
|
`verify` int(11) DEFAULT NULL,
|
||||||
|
`status` int(11) DEFAULT NULL,
|
||||||
|
`two_factor_authentication` int(11) DEFAULT NULL,
|
||||||
|
`force_password_change` tinyint(1) DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.credential: ~2 rows (approximately)
|
||||||
|
DELETE FROM `credential`;
|
||||||
|
/*!40000 ALTER TABLE `credential` DISABLE KEYS */;
|
||||||
|
INSERT INTO `credential` (`id`, `oauth`, `email`, `password`, `user_id`, `type`, `verify`, `status`, `two_factor_authentication`, `force_password_change`, `created_at`, `updated_at`) VALUES
|
||||||
|
(1, NULL, 'admin@manaknight.com', '$2a$04$tQm/w6gJNKOoiZOn0WVISe1xG7BD1ulw72UNHXsXgLObtdKjlMhZK', 1, 0, 1, 1, 0, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(2, NULL, 'member@manaknight.com', '$2a$04$A7JX0xG2Gwt06UKpxq/Yd.oJARP6.BpzkzjOhc67.2dkfqjJPJ0pe', 2, 0, 1, 1, 0, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43');
|
||||||
|
/*!40000 ALTER TABLE `credential` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.email
|
||||||
|
DROP TABLE IF EXISTS `email`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `email` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`slug` varchar(255) DEFAULT NULL,
|
||||||
|
`subject` text DEFAULT NULL,
|
||||||
|
`tag` text DEFAULT NULL,
|
||||||
|
`html` text DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.email: ~4 rows (approximately)
|
||||||
|
DELETE FROM `email`;
|
||||||
|
/*!40000 ALTER TABLE `email` DISABLE KEYS */;
|
||||||
|
INSERT INTO `email` (`id`, `slug`, `subject`, `tag`, `html`, `created_at`, `updated_at`) VALUES
|
||||||
|
(1, 'reset-password', 'Reset your password', 'email,reset_token,link', 'Hi {{{email}}},<br/>You have requested to reset your password. Please click the link below to reset it.<br/><a href="{{{link}}}/{{{reset_token}}}">Link</a>. <br/>Thanks,<br/> Admin', '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(2, 'register', 'Register', 'email', 'Hi {{{email}}},<br/>Thanks for registering on our platform. <br/>Thanks,<br/> Admin', '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(3, 'confirm-password', 'Confirm your account', 'email,confirm_token,link', 'Hi {{{email}}},<br/>Please click the link below to confirm your account.<br/><a href="{{{link}}}/{{{confirm_token}}}">Link</a>Thanks,<br/> Admin', '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(4, 'verify', 'Account verification', 'code', 'Your verification # is {{{code}}}', '2022-04-10 11:07:43', '2022-04-10 11:07:43');
|
||||||
|
/*!40000 ALTER TABLE `email` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.image
|
||||||
|
DROP TABLE IF EXISTS `image`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `image` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`url` text DEFAULT NULL,
|
||||||
|
`caption` text DEFAULT NULL,
|
||||||
|
`user_id` int(11) DEFAULT NULL,
|
||||||
|
`width` int(11) DEFAULT NULL,
|
||||||
|
`height` int(11) DEFAULT NULL,
|
||||||
|
`mobile_width` int(11) DEFAULT NULL,
|
||||||
|
`mobile_height` int(11) DEFAULT NULL,
|
||||||
|
`upload_type` int(11) DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.image: ~35 rows (approximately)
|
||||||
|
DELETE FROM `image`;
|
||||||
|
/*!40000 ALTER TABLE `image` DISABLE KEYS */;
|
||||||
|
INSERT INTO `image` (`id`, `url`, `caption`, `user_id`, `width`, `height`, `mobile_width`, `mobile_height`, `upload_type`, `created_at`, `updated_at`) VALUES
|
||||||
|
(1, '/image/profile.png', '', 1, 581, 581, 348, 348, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(2, '/frontend_images/Icons/SVG/Skin Sensitivity/Non Sensitive Skin.svg', '', 1, 183, 183, 183, 183, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(3, '/frontend_images/Icons/SVG/Skin Sensitivity/Moderately Sensitive.svg', '', 1, 183, 183, 183, 183, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(4, '/frontend_images/Icons/SVG/Skin Sensitivity/Extremely Sensitive.svg', '', 1, 183, 183, 183, 183, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(5, '/frontend_images/Icons/SVG/Dry_Oily Skin/Dry Skin.svg', '', 1, 191, 191, 191, 191, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(6, '/frontend_images/Icons/SVG/Dry_Oily Skin/Normal and Combination.svg', '', 1, 191, 191, 191, 191, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(7, '/frontend_images/Icons/SVG/Dry_Oily Skin/Oily.svg', '', 1, 191, 191, 191, 191, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(8, '/frontend_images/SkintoneGraphics/1.png', '', 1, 74, 135, 74, 135, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(9, '/frontend_images/SkintoneGraphics/2.png', '', 1, 74, 135, 74, 135, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(10, '/frontend_images/SkintoneGraphics/3.png', '', 1, 74, 135, 74, 135, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(11, '/frontend_images/SkintoneGraphics/4.png', '', 1, 74, 135, 74, 135, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(12, '/frontend_images/SkintoneGraphics/5.png', '', 1, 74, 135, 74, 135, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(13, '/frontend_images/SkintoneGraphics/6.png', '', 1, 74, 135, 74, 135, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(14, '/frontend_images/SkintoneGraphics/7.png', '', 1, 74, 135, 74, 135, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(15, '/frontend_images/SkintoneGraphics/8.png', '', 1, 74, 135, 74, 135, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(16, '/frontend_images/SkintoneGraphics/9.png', '', 1, 74, 135, 74, 135, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(17, '/frontend_images/SkintoneGraphics/10.png', '', 1, 74, 135, 74, 135, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(18, '/frontend_images/SkintoneGraphics/11.png', '', 1, 74, 135, 74, 135, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(19, '/frontend_images/SkintoneGraphics/12.png', '', 1, 74, 135, 74, 135, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(20, '/frontend_images/SkintoneGraphics/13.png', '', 1, 74, 135, 74, 135, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(21, '/frontend_images/SkintoneGraphics/14.png', '', 1, 74, 135, 74, 135, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(22, '/frontend_images/SkintoneGraphics/15.png', '', 1, 74, 135, 74, 135, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(23, '/frontend_images/Icons/SVG/Blotchiness/No Blotchiness.svg', '', 1, 240, 240, 240, 240, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(24, '/frontend_images/Icons/PNG/Blotchiness/Lot\'s of Blotchiness.png', '', 1, 240, 240, 240, 240, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(25, '/frontend_images/Icons/SVG/Face Lines/No Wrinkles.svg', '', 1, 240, 240, 240, 240, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(26, '/frontend_images/Icons/SVG/Face Lines/A Few Lines.svg', '', 1, 240, 240, 240, 240, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(27, '/frontend_images/Icons/SVG/Face Lines/A Few Lines Observable at all times.svg', '', 1, 240, 240, 240, 240, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(28, '/frontend_images/Icons/SVG/Face Lines/Some Lines.svg', '', 1, 240, 240, 240, 240, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(29, '/frontend_images/Icons/SVG/Face Lines/Lines Plus Hints of Wrinkles.svg', '', 1, 240, 240, 240, 240, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(30, '/frontend_images/Icons/SVG/Face Lines/A Few Wrinkles.svg', '', 1, 240, 240, 240, 240, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(31, '/frontend_images/Icons/SVG/Face Lines/Lots of Wrinkles.svg', '', 1, 240, 240, 240, 240, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(32, '/frontend_images/Icons/SVG/Water/1 Glass of Water.svg', '', 1, 140, 190, 140, 190, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(33, '/frontend_images/Icons/SVG/Water/4 Glasses of Water.svg', '', 1, 140, 190, 140, 190, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(34, '/frontend_images/Icons/SVG/Water/8 Glasses of Water.svg', '', 1, 140, 190, 140, 190, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(35, '/frontend_images/MainImage/main_quiz_image.png', NULL, 1, NULL, NULL, NULL, NULL, NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43');
|
||||||
|
/*!40000 ALTER TABLE `image` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.member_operation
|
||||||
|
DROP TABLE IF EXISTS `member_operation`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `member_operation` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`action` varchar(255) DEFAULT NULL,
|
||||||
|
`detail` text DEFAULT NULL,
|
||||||
|
`last_ip` varchar(255) DEFAULT NULL,
|
||||||
|
`user_agent` varchar(255) DEFAULT NULL,
|
||||||
|
`status` int(11) DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
`user_id` int(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.member_operation: ~0 rows (approximately)
|
||||||
|
DELETE FROM `member_operation`;
|
||||||
|
/*!40000 ALTER TABLE `member_operation` DISABLE KEYS */;
|
||||||
|
/*!40000 ALTER TABLE `member_operation` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.order
|
||||||
|
DROP TABLE IF EXISTS `order`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `order` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`webhook_id` varchar(255) DEFAULT NULL,
|
||||||
|
`shopify_id` varchar(255) DEFAULT NULL,
|
||||||
|
`event` text DEFAULT NULL,
|
||||||
|
`customer_shopify_id` varchar(255) DEFAULT NULL,
|
||||||
|
`customer` text DEFAULT NULL,
|
||||||
|
`answers` text DEFAULT NULL,
|
||||||
|
`profile` text DEFAULT NULL,
|
||||||
|
`actives` text DEFAULT NULL,
|
||||||
|
`items` text DEFAULT NULL,
|
||||||
|
`financial_status` varchar(255) DEFAULT NULL,
|
||||||
|
`fulfillment_status` varchar(255) DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `webhook_id` (`webhook_id`),
|
||||||
|
UNIQUE KEY `shopify_id` (`shopify_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.order: ~0 rows (approximately)
|
||||||
|
DELETE FROM `order`;
|
||||||
|
/*!40000 ALTER TABLE `order` DISABLE KEYS */;
|
||||||
|
/*!40000 ALTER TABLE `order` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.output_variable
|
||||||
|
DROP TABLE IF EXISTS `output_variable`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `output_variable` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` varchar(255) DEFAULT NULL,
|
||||||
|
`priority` float DEFAULT NULL,
|
||||||
|
`active_list` text DEFAULT NULL,
|
||||||
|
`ranges_response` text DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.output_variable: ~25 rows (approximately)
|
||||||
|
DELETE FROM `output_variable`;
|
||||||
|
INSERT INTO `output_variable` (`id`, `name`, `priority`, `active_list`, `ranges_response`, `created_at`, `updated_at`) VALUES
|
||||||
|
(1, 'Bio Age', 0, NULL, '[{"0-33":""},{"34-66":""},{"67-100":""}]', '2021-12-28 15:27:57', '2022-01-04 15:15:29'),
|
||||||
|
(2, 'Age', 70, NULL, '[{"0-33":""},{"34-66":""},{"67-100":""}]', '2021-12-28 15:27:57', '2022-01-04 15:15:45'),
|
||||||
|
(3, 'Gender', 75, NULL, '[{"0-33":""},{"34-66":""},{"67-100":""}]', '2021-12-28 15:27:57', '2022-01-04 15:16:07'),
|
||||||
|
(4, 'Pregnancy', 100, NULL, '[{"0-33":""},{"34-66":""},{"67-100":""}]', '2021-12-28 15:27:57', '2022-01-04 15:16:18'),
|
||||||
|
(5, 'Hair', 75, NULL, '[{"0-33":""},{"34-66":""},{"67-100":""}]', '2021-12-28 15:27:57', '2022-01-04 15:16:30'),
|
||||||
|
(6, 'Sensitivity', 90, NULL, '[{"0-33":"Your skin is not that sensitive"},{"34-66":"Your skin is somewhat sensitive"},{"67-100":"Your skin is highly sensitive"}]', '2021-12-28 15:27:57', '2022-01-04 15:16:53'),
|
||||||
|
(7, 'Hydration', 100, NULL, '[{"0-33":"Your skin is relatively well hydrated"},{"34-66":"Your skin may need a little more hydration"},{"67-100":"Your skin is in need of extra Hydration"}]', '2021-12-28 15:27:57', '2022-02-21 23:43:06'),
|
||||||
|
(8, 'Breakouts', 100, NULL, '[{"0-33":"Your skin is not very breakout prone"},{"34-66":"Your skin is prone to occasional breakouts"},{"67-100":"Your skin is highly breakout prone"}]', '2021-12-28 15:27:57', '2022-01-04 15:18:40'),
|
||||||
|
(9, 'Color', 50, NULL, '[{"0-33":""},{"34-66":""},{"67-100":""}]', '2021-12-28 15:27:57', '2022-01-04 15:18:52'),
|
||||||
|
(10, 'Sun', 95, NULL, '[{"0-33":"Your skin isn\'t as sensitive to the sun but still requires some protection"},{"34-66":"Your skin needs some sun protection"},{"67-100":"Your skin requires extra sun protection"}]', '2021-12-28 15:27:57', '2022-01-23 15:10:31'),
|
||||||
|
(11, 'Hyperpigmentation', 90, NULL, '[{"0-33":"Your skin is not very prone to hyperpigmentation"},{"34-66":"Your skin is somewhat prone to some hyperpigmentation"},{"67-100":"Your skin is prone to hyperpigmentation"}]', '2021-12-28 15:27:57', '2022-01-23 15:11:30'),
|
||||||
|
(12, 'Hypopigmentation', 90, NULL, '[{"0-33":""},{"34-66":""},{"67-100":""}]', '2021-12-28 15:27:57', '2022-01-23 15:11:47'),
|
||||||
|
(13, 'Redness', 85, NULL, '[{"0-33":"Your skin is not especially prone to redness"},{"34-66":"Your skin is somewhat prone to redness"},{"67-100":"Your skin is highly prone to experience redness"}]', '2021-12-28 15:27:57', '2022-02-21 15:21:32'),
|
||||||
|
(14, 'Lines', 100, NULL, '[{"0-33":"Your skin is relatively smooth"},{"34-66":"Your skin has some fine lines"},{"67-100":"Your skin can use an extra boost of anti-aging actives"}]', '2021-12-28 15:27:57', '2022-01-23 15:17:50'),
|
||||||
|
(15, 'Firmness', 100, NULL, '[{"0-33":"Your skin is relatively firm"},{"34-66":"Your skin can use a boost to maintain firmness"},{"67-100":"Your skin will benefit from an extra boost to its firmness"}]', '2021-12-28 15:27:57', '2022-02-21 15:22:53'),
|
||||||
|
(16, 'Pores', 70, NULL, '[{"0-33":"You don\'t have many visible pores"},{"34-66":"You have some visible pores"},{"67-100":"You have significant visible pores"}]', '2021-12-28 15:27:57', '2022-01-23 15:25:45'),
|
||||||
|
(17, 'Blackheads', 65, NULL, '[{"0-33":"Your skin has relatively few visible blackheads"},{"34-66":"Your skin has some visible blackheads"},{"67-100":"Your skin has visible blackheads"}]', '2021-12-28 15:27:57', '2022-05-27 11:43:45'),
|
||||||
|
(18, 'Allergies', 100, NULL, '[{"0-33":""},{"34-66":""},{"67-100":""}]', '2021-12-28 15:27:57', '2022-01-23 15:28:22'),
|
||||||
|
(19, 'Pollution', 80, NULL, '[{"0-33":"Your skin is exposed to relatively low levels of pollution"},{"34-66":"Your skin is exposed to some pollution"},{"67-100":"Your skin is exposed to significant pollution"}]', '2021-12-28 15:27:57', '2022-01-23 15:26:54'),
|
||||||
|
(20, 'Temperature', 0, NULL, '[{"0-33":""},{"34-66":""},{"67-100":""}]', '2021-12-28 15:27:57', '2022-01-23 15:26:03'),
|
||||||
|
(21, 'Stress', 40, NULL, '[{"0-33":""},{"34-66":""},{"67-100":""}]', '2021-12-28 15:27:57', '2022-01-23 15:29:18'),
|
||||||
|
(22, 'Diet', 30, NULL, '[{"0-33":""},{"34-66":""},{"67-100":""}]', '2021-12-28 15:27:57', '2022-01-23 15:30:41'),
|
||||||
|
(23, 'Sleep', 20, NULL, '[{"0-33":""},{"34-66":""},{"67-100":""}]', '2021-12-28 15:27:57', '2022-01-23 15:30:28'),
|
||||||
|
(24, 'Blue Light', 45, NULL, '[{"0-33":""},{"34-66":""},{"67-100":""}]', '2021-12-28 15:27:57', '2022-01-23 15:29:04'),
|
||||||
|
(25, 'Oxygenation', 40, NULL, '[{"0-33":""},{"34-66":""},{"67-100":""}]', '2021-12-28 15:27:57', '2022-01-23 15:28:48');
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.question
|
||||||
|
DROP TABLE IF EXISTS `question`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `question` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`quiz_id` int(11) DEFAULT NULL,
|
||||||
|
`question` text DEFAULT NULL,
|
||||||
|
`question_arguments` text DEFAULT NULL,
|
||||||
|
`order` int(11) DEFAULT NULL,
|
||||||
|
`image_width` float DEFAULT NULL,
|
||||||
|
`image_height` float DEFAULT NULL,
|
||||||
|
`placeholder` varchar(255) DEFAULT NULL,
|
||||||
|
`note` text DEFAULT NULL,
|
||||||
|
`note_type` int(11) DEFAULT NULL,
|
||||||
|
`target` int(11) DEFAULT NULL,
|
||||||
|
`response` text DEFAULT NULL,
|
||||||
|
`save_response_into` varchar(255) DEFAULT NULL,
|
||||||
|
`depends_on` varchar(255) DEFAULT NULL,
|
||||||
|
`slider_range` varchar(255) DEFAULT NULL,
|
||||||
|
`output_variable_name` varchar(255) DEFAULT NULL,
|
||||||
|
`weight` float DEFAULT NULL,
|
||||||
|
`extra_output_variable` text DEFAULT NULL,
|
||||||
|
`type` int(11) DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.question: ~30 rows (approximately)
|
||||||
|
DELETE FROM `question`;
|
||||||
|
/*!40000 ALTER TABLE `question` DISABLE KEYS */;
|
||||||
|
INSERT INTO `question` (`id`, `quiz_id`, `question`, `question_arguments`, `order`, `image_width`, `image_height`, `placeholder`, `note`, `note_type`, `target`, `response`, `save_response_into`, `depends_on`, `slider_range`, `output_variable_name`, `weight`, `extra_output_variable`, `type`, `created_at`, `updated_at`) VALUES
|
||||||
|
(1, 1, 'What would you like to be called?', NULL, 1, NULL, NULL, 'name', NULL, NULL, 4, NULL, 'name', NULL, NULL, NULL, NULL, NULL, 1, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(2, 1, ' When were you born <<<name>>>?', '["name"]', 2, NULL, NULL, 'year', 'Your age plays an important role on which functional actives we may want to focus on for your skin assessment.', 2, 4, NULL, 'age', NULL, NULL, 'Bio Age', 100, '[{"name":"Age","weight":50}]', 3, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(3, 1, 'What is your hormonal gender', NULL, 3, NULL, NULL, NULL, 'Your hormones play an important role in your skin’s health and appearance.', 1, 4, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 4, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(4, 1, 'Are you pregnant or breastfeeding?', NULL, 4, NULL, NULL, NULL, 'Hormonal changes during pregnancy can lead to visible changes in skin appearance. It’s also very important to ensure that all actives are proven safe for this important period.', 2, 1, NULL, NULL, '3|female', NULL, 'Pregnancy', 100, NULL, 4, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(5, 1, 'What is your facial hair situation?', NULL, 5, NULL, NULL, NULL, 'Presence of hair on face can have an effect on the skin beneath.', 2, 2, NULL, NULL, '3|male', NULL, 'Hair', 100, NULL, 4, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(6, 2, 'How Sensitive is your skin?', NULL, 1, NULL, NULL, NULL, 'We’ll be more careful of which actives we add to formula for those with more sensitive skin types. It’s all about balancing effectivity, complexity and leaving you feeling your best.', 2, 4, NULL, NULL, NULL, '0-100', 'Sensitivity', 100, NULL, 6, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(7, 2, 'How would you describe your skin on an average day?', NULL, 2, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, '0-100', 'Hydration', 70, NULL, 6, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(8, 2, 'How often do you have breakouts, such as an occasional pimple or frequent breakouts (such as chronic acne)?', NULL, 3, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, '0-100', 'Breakouts', 100, NULL, 6, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(9, 2, 'What’s your skintone without a suntan?', NULL, 4, 60, 110, NULL, 'Different skin tones are associated with different levels of skin melanin, leading to differing reactions of skin to the effects of the sun.', 2, 4, NULL, NULL, NULL, NULL, 'Color', 100, '[{"name":"Sun","weight":10},{"name":"Hyperpigmentation","weight":10}]', 5, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(10, 2, 'How easily does your skin tan?', NULL, 5, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, '0-100', 'Sun', 20, NULL, 6, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(11, 2, 'Is your skin prone to Hyperpigmentation?', NULL, 6, NULL, NULL, NULL, 'This is the likelihood of skin discoloring associated with aging or after injury.', 1, 4, NULL, NULL, NULL, '0-100', 'Hyperpigmentation', 90, '[{"name":"Sun","weight":10}]', 6, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(12, 2, 'How easily does your skin burn in the sun?', NULL, 8, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, '0-100', 'Sun', 60, NULL, 6, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(13, 2, 'How often does your skin experience redness?', NULL, 9, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, '0-100', 'Redness', 100, NULL, 6, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(14, 2, 'Halfway There! Do you want to save your progress?', NULL, 10, NULL, NULL, 'email', NULL, NULL, 4, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(15, 2, 'Which best describes your face?', NULL, 11, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, '0-100', 'Lines', 100, '[{"name":"Age","weight":30}]', 6, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(16, 2, 'How firm is your skin?', NULL, 12, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, '0-100', 'Firmness', 100, '[{"name":"Age","weight":20}]', 6, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(17, 2, 'Do you have enlarged pores?', NULL, 13, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, '0-100', 'Pores', 100, NULL, 6, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(18, 2, 'Do you have blackheads?', NULL, 14, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, '0-100', 'Blackheads', 100, NULL, 6, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(19, 2, 'Do you have any known allergies?', NULL, 15, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, NULL, 'Allergies', 100, NULL, 4, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(20, 2, 'Do you know if you have allergies to any of the following?', NULL, 16, NULL, NULL, NULL, NULL, NULL, 4, 'We’ll make sure to leave those out', NULL, '19|yes', NULL, NULL, NULL, NULL, 7, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(21, 3, 'Let’s adjust your cream to your geography. Enter your city below', NULL, 1, NULL, NULL, 'city', NULL, NULL, 4, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 8, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(22, 3, 'How often do you smoke?', NULL, 2, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, '0-100', 'Pollution', 33, NULL, 6, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(23, 3, 'How would you describe your stress levels?', NULL, 3, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, '0-100', 'Stress', 100, NULL, 6, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(24, 3, 'Which of these closest resembles your diet?', NULL, 4, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, NULL, 'Diet', 100, NULL, 4, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(25, 3, 'On average how many hours of sleep do you get a night?', NULL, 5, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, '4-8', 'Sleep', 100, NULL, 6, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(26, 3, 'How many hours a day do you sit in front of a screen, ex phone, computer, tv etc.?', NULL, 6, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, '0-6', 'Blue Light', 100, NULL, 6, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(27, 3, 'On average, how many glasses of water do you drink a day?', NULL, 7, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, '0-100', 'Hydration', 15, NULL, 6, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(28, 3, 'How much makeup do you wear on a daily basis?', NULL, 8, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, '0-100', 'Pollution', 33.33, NULL, 6, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(29, 3, 'On average, how many hours a week do you excercize?', NULL, 9, NULL, NULL, NULL, NULL, NULL, 4, NULL, NULL, NULL, '0-100', 'Oxygenation', 100, NULL, 6, '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(30, 2, 'Is your skin prone to Hypopigmentation?', NULL, 7, NULL, NULL, NULL, 'This is the likelihood of skin discoloring associated with aging or after injury.', 1, NULL, NULL, NULL, '', '0-100', 'Hypopigmentation', 100, NULL, 6, '2022-04-10 11:07:43', '2022-04-10 11:07:43');
|
||||||
|
/*!40000 ALTER TABLE `question` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.quiz
|
||||||
|
DROP TABLE IF EXISTS `quiz`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `quiz` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` varchar(255) DEFAULT NULL,
|
||||||
|
`description` text DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.quiz: ~3 rows (approximately)
|
||||||
|
DELETE FROM `quiz`;
|
||||||
|
/*!40000 ALTER TABLE `quiz` DISABLE KEYS */;
|
||||||
|
INSERT INTO `quiz` (`id`, `name`, `description`, `created_at`, `updated_at`) VALUES
|
||||||
|
(1, 'The Basics', 'Let’s start by getting to know you.', '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(2, 'Your Skin', 'Let’s learn about your skin and it’s uniqueness.', '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(3, 'Your Environment', 'Almost done, let’s talk environment & lifestyle.', '2022-04-10 11:07:43', '2022-04-10 11:07:43');
|
||||||
|
/*!40000 ALTER TABLE `quiz` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.refer_log
|
||||||
|
DROP TABLE IF EXISTS `refer_log`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `refer_log` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`user_id` int(11) DEFAULT NULL,
|
||||||
|
`referrer_user_id` int(11) DEFAULT NULL,
|
||||||
|
`type` int(11) DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.refer_log: ~0 rows (approximately)
|
||||||
|
DELETE FROM `refer_log`;
|
||||||
|
/*!40000 ALTER TABLE `refer_log` DISABLE KEYS */;
|
||||||
|
/*!40000 ALTER TABLE `refer_log` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.result_profile
|
||||||
|
DROP TABLE IF EXISTS `result_profile`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `result_profile` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`section_title` varchar(255) DEFAULT NULL,
|
||||||
|
`output_variable_list` text DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.result_profile: ~3 rows (approximately)
|
||||||
|
DELETE FROM `result_profile`;
|
||||||
|
/*!40000 ALTER TABLE `result_profile` DISABLE KEYS */;
|
||||||
|
INSERT INTO `result_profile` (`id`, `section_title`, `output_variable_list`, `created_at`, `updated_at`) VALUES
|
||||||
|
(1, 'Skin Sensitivity', '[6,7,13,11,10]', '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(2, 'Skin Characteristics', '[14,15,17,16,8]', '2022-04-10 11:07:44', '2022-04-10 11:07:44'),
|
||||||
|
(3, 'Environmental Factors', '[19,21,24,25]', '2022-04-10 11:07:44', '2022-04-10 11:07:44');
|
||||||
|
/*!40000 ALTER TABLE `result_profile` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.role
|
||||||
|
DROP TABLE IF EXISTS `role`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `role` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` varchar(255) DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.role: ~2 rows (approximately)
|
||||||
|
DELETE FROM `role`;
|
||||||
|
/*!40000 ALTER TABLE `role` DISABLE KEYS */;
|
||||||
|
INSERT INTO `role` (`id`, `name`, `created_at`, `updated_at`) VALUES
|
||||||
|
(1, 'admin', '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(2, 'member', '2022-04-10 11:07:43', '2022-04-10 11:07:43');
|
||||||
|
/*!40000 ALTER TABLE `role` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.rule
|
||||||
|
DROP TABLE IF EXISTS `rule`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `rule` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`output_variable_name` varchar(255) DEFAULT NULL,
|
||||||
|
`actives` text DEFAULT NULL,
|
||||||
|
`operator` int(11) DEFAULT NULL,
|
||||||
|
`compare_value` float DEFAULT NULL,
|
||||||
|
`min` float DEFAULT NULL,
|
||||||
|
`max` float DEFAULT NULL,
|
||||||
|
`action` int(11) DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.rule: ~1 rows (approximately)
|
||||||
|
DELETE FROM `rule`;
|
||||||
|
/*!40000 ALTER TABLE `rule` DISABLE KEYS */;
|
||||||
|
INSERT INTO `rule` (`id`, `output_variable_name`, `actives`, `operator`, `compare_value`, `min`, `max`, `action`, `created_at`, `updated_at`) VALUES
|
||||||
|
(1, 'Age', '["Camomile"]', 3, 30, NULL, NULL, 2, '2022-04-10 11:07:43', '2022-04-10 11:07:43');
|
||||||
|
/*!40000 ALTER TABLE `rule` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.setting
|
||||||
|
DROP TABLE IF EXISTS `setting`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `setting` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`key` varchar(255) DEFAULT NULL,
|
||||||
|
`type` int(11) DEFAULT NULL,
|
||||||
|
`value` text DEFAULT NULL,
|
||||||
|
`maintenance` int(11) DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.setting: ~6 rows (approximately)
|
||||||
|
DELETE FROM `setting`;
|
||||||
|
/*!40000 ALTER TABLE `setting` DISABLE KEYS */;
|
||||||
|
INSERT INTO `setting` (`id`, `key`, `type`, `value`, `maintenance`, `created_at`, `updated_at`) VALUES
|
||||||
|
(1, 'site_name', 0, 'Createdby', NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(2, 'site_logo', 0, 'https://createdby.co/assets/img/logo.png', NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(3, 'maintenance', 1, '0', NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(4, 'version', 0, '1.0.0', NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(5, 'copyright', 0, 'Copyright © 2021 Createdby. All rights reserved.', NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43'),
|
||||||
|
(6, 'license_key', 4, '4097fbd4f340955de76ca555c201b185cf9d6921d977301b05cdddeae4af54f924f0508cd0f7ca66', NULL, '2022-04-10 11:07:43', '2022-04-10 11:07:43');
|
||||||
|
/*!40000 ALTER TABLE `setting` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.sms
|
||||||
|
DROP TABLE IF EXISTS `sms`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `sms` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`slug` varchar(255) DEFAULT NULL,
|
||||||
|
`tag` text DEFAULT NULL,
|
||||||
|
`content` text DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.sms: ~1 rows (approximately)
|
||||||
|
DELETE FROM `sms`;
|
||||||
|
/*!40000 ALTER TABLE `sms` DISABLE KEYS */;
|
||||||
|
INSERT INTO `sms` (`id`, `slug`, `tag`, `content`, `created_at`, `updated_at`) VALUES
|
||||||
|
(1, 'verify', 'code', 'Your verification # is {{{code}}}', '2022-04-10 11:07:43', '2022-04-10 11:07:43');
|
||||||
|
/*!40000 ALTER TABLE `sms` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.token
|
||||||
|
DROP TABLE IF EXISTS `token`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `token` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`token` text DEFAULT NULL,
|
||||||
|
`data` text DEFAULT NULL,
|
||||||
|
`type` int(11) DEFAULT NULL,
|
||||||
|
`user_id` int(11) DEFAULT NULL,
|
||||||
|
`ttl` int(11) DEFAULT NULL,
|
||||||
|
`issue_at` datetime DEFAULT NULL,
|
||||||
|
`expire_at` datetime DEFAULT NULL,
|
||||||
|
`status` int(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.token: ~0 rows (approximately)
|
||||||
|
DELETE FROM `token`;
|
||||||
|
/*!40000 ALTER TABLE `token` DISABLE KEYS */;
|
||||||
|
/*!40000 ALTER TABLE `token` ENABLE KEYS */;
|
||||||
|
|
||||||
|
-- Dumping structure for table mkd.user
|
||||||
|
DROP TABLE IF EXISTS `user`;
|
||||||
|
CREATE TABLE IF NOT EXISTS `user` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`role_id` int(11) DEFAULT NULL,
|
||||||
|
`profile_id` int(11) DEFAULT NULL,
|
||||||
|
`organization_id` int(11) DEFAULT NULL,
|
||||||
|
`first_name` varchar(255) DEFAULT NULL,
|
||||||
|
`last_name` varchar(255) DEFAULT NULL,
|
||||||
|
`phone` varchar(255) DEFAULT NULL,
|
||||||
|
`image` text DEFAULT NULL,
|
||||||
|
`refer` varchar(255) DEFAULT NULL,
|
||||||
|
`stripe_uid` varchar(255) DEFAULT NULL,
|
||||||
|
`paypal_uid` varchar(255) DEFAULT NULL,
|
||||||
|
`expire_at` date DEFAULT NULL,
|
||||||
|
`status` int(11) DEFAULT NULL,
|
||||||
|
`created_at` datetime NOT NULL,
|
||||||
|
`updated_at` datetime NOT NULL,
|
||||||
|
`user_id` int(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Dumping data for table mkd.user: ~2 rows (approximately)
|
||||||
|
DELETE FROM `user`;
|
||||||
|
/*!40000 ALTER TABLE `user` DISABLE KEYS */;
|
||||||
|
INSERT INTO `user` (`id`, `role_id`, `profile_id`, `organization_id`, `first_name`, `last_name`, `phone`, `image`, `refer`, `stripe_uid`, `paypal_uid`, `expire_at`, `status`, `created_at`, `updated_at`, `user_id`) VALUES
|
||||||
|
(1, 1, NULL, NULL, 'Admin', 'Admin', '12345678', '/image/profile.png', 'admin', NULL, NULL, NULL, 1, '2022-04-10 11:07:43', '2022-04-10 11:07:43', NULL),
|
||||||
|
(2, 2, NULL, NULL, 'Member', 'Member', '12345678', '/image/profile.png', 'member', NULL, NULL, NULL, 1, '2022-04-10 11:07:43', '2022-04-10 11:07:43', NULL);
|
||||||
|
/*!40000 ALTER TABLE `user` ENABLE KEYS */;
|
||||||
|
|
||||||
|
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
|
||||||
|
/*!40014 SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS, 1) */;
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40111 SET SQL_NOTES=IFNULL(@OLD_SQL_NOTES, 1) */;
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* active Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require("bcryptjs");
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require("lodash");
|
||||||
|
const coreModel = require("./../core/models");
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Active = sequelize.define(
|
||||||
|
"active",
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
name: DataTypes.STRING,
|
||||||
|
handle: DataTypes.TEXT,
|
||||||
|
description: DataTypes.TEXT,
|
||||||
|
variables_scores: DataTypes.TEXT,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "active",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Active);
|
||||||
|
|
||||||
|
Active._preCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Active._postCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Active._customCountingConditions = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Active._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Active.allowFields();
|
||||||
|
allowedFields.push(Active._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Active.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Active.associate = function (models) {};
|
||||||
|
|
||||||
|
Active.allowFields = function () {
|
||||||
|
return ["id", "name", "handle", "variables_scores", "description"];
|
||||||
|
};
|
||||||
|
|
||||||
|
Active.labels = function () {
|
||||||
|
return ["ID", "Name", "Handle", "Variables scores", "Description"];
|
||||||
|
};
|
||||||
|
|
||||||
|
Active.validationRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["name", "Name", "required"],
|
||||||
|
["variables_scores", "Variables scores", ""],
|
||||||
|
["description", "Description", ""],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Active.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["name", "Name", "required"],
|
||||||
|
["variables_scores", "Variables scores", ""],
|
||||||
|
["description", "Description", ""],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Active.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(["id", "name", "handle", "variables_scores", "description", "created_at", "updated_at"], Object.keys(fields));
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
return Active;
|
||||||
|
};
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* activity_log Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require('bcryptjs');
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require('lodash');
|
||||||
|
const coreModel = require('./../core/models');
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Activity_log = sequelize.define(
|
||||||
|
"activity_log",
|
||||||
|
{
|
||||||
|
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
name: DataTypes.STRING,
|
||||||
|
action: DataTypes.STRING,
|
||||||
|
data: DataTypes.TEXT,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "activity_log",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Activity_log);
|
||||||
|
|
||||||
|
Activity_log._preCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Activity_log._postCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Activity_log._customCountingConditions = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Activity_log._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Activity_log.allowFields();
|
||||||
|
allowedFields.push(Activity_log._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Activity_log.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Activity_log.associate = function(models) { };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Activity_log.allowFields = function () {
|
||||||
|
return ['id','name','action','data',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Activity_log.labels = function () {
|
||||||
|
return ['ID','Name','Action','Data',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Activity_log.validationRules = function () {
|
||||||
|
return [
|
||||||
|
['id', 'ID', ''],
|
||||||
|
['name', 'Name', ''],
|
||||||
|
['action', 'Action', 'required'],
|
||||||
|
['data', 'Data', 'required'],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Activity_log.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
['id', 'ID', ''],
|
||||||
|
['name', 'Name', ''],
|
||||||
|
['action', 'Action', 'required'],
|
||||||
|
['data', 'Data', 'required'],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Activity_log.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(
|
||||||
|
[
|
||||||
|
'id','name','action','data','created_at','updated_at',
|
||||||
|
],
|
||||||
|
Object.keys(fields),
|
||||||
|
);
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return Activity_log;
|
||||||
|
};
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* admin_operation Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require('bcryptjs');
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require('lodash');
|
||||||
|
const coreModel = require('./../core/models');
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Admin_operation = sequelize.define(
|
||||||
|
"admin_operation",
|
||||||
|
{
|
||||||
|
user_id: DataTypes.INTEGER,
|
||||||
|
action: DataTypes.STRING,
|
||||||
|
detail: DataTypes.TEXT,
|
||||||
|
last_ip: DataTypes.STRING,
|
||||||
|
user_agent: DataTypes.STRING,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "admin_operation",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Admin_operation);
|
||||||
|
|
||||||
|
Admin_operation._preCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Admin_operation._postCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Admin_operation._customCountingConditions = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Admin_operation._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Admin_operation.allowFields();
|
||||||
|
allowedFields.push(Admin_operation._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Admin_operation.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Admin_operation.associate = function(models) {
|
||||||
|
Admin_operation.belongsTo(models.user, {
|
||||||
|
foreignKey: "user_id",
|
||||||
|
as: "user",
|
||||||
|
constraints: false,
|
||||||
|
}) };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Admin_operation.allowFields = function () {
|
||||||
|
return ['user_id','action','detail','last_ip','user_agent',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Admin_operation.labels = function () {
|
||||||
|
return ['User','Action','Detail','Last IP','User Agent',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Admin_operation.validationRules = function () {
|
||||||
|
return [
|
||||||
|
['user_id', 'User', 'required|integer'],
|
||||||
|
['action', 'Action', 'required|max[50]'],
|
||||||
|
['detail', 'Detail', 'required'],
|
||||||
|
['last_ip', 'Last IP', 'required'],
|
||||||
|
['user_agent', 'User Agent', 'required'],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Admin_operation.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
['user_id', 'User', ''],
|
||||||
|
['action', 'Action', ''],
|
||||||
|
['detail', 'Detail', ''],
|
||||||
|
['last_ip', 'Last IP', ''],
|
||||||
|
['user_agent', 'User Agent', ''],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Admin_operation.get_user_paginated = function(db, where = {}, ...rest) {
|
||||||
|
return Admin_operation.getPaginated(...rest, [{
|
||||||
|
model: db.user,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "user",
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Admin_operation.get_admin_operation_user = (id, db) => {
|
||||||
|
return Admin_operation.findByPk(id,
|
||||||
|
{
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.user,
|
||||||
|
required: false,
|
||||||
|
as: "user",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Admin_operation.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(
|
||||||
|
[
|
||||||
|
'user_id','action','detail','last_ip','user_agent','created_at','updated_at',
|
||||||
|
],
|
||||||
|
Object.keys(fields),
|
||||||
|
);
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return Admin_operation;
|
||||||
|
};
|
||||||
@@ -0,0 +1,214 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* answer Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require("bcryptjs");
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require("lodash");
|
||||||
|
const coreModel = require("./../core/models");
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Answer = sequelize.define(
|
||||||
|
"answer",
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
question_id: DataTypes.INTEGER,
|
||||||
|
order: DataTypes.INTEGER,
|
||||||
|
answer: DataTypes.TEXT,
|
||||||
|
answer_value: DataTypes.FLOAT,
|
||||||
|
hide_answer: DataTypes.BOOLEAN,
|
||||||
|
explaination: DataTypes.TEXT,
|
||||||
|
image_id: DataTypes.TEXT,
|
||||||
|
response_header: DataTypes.TEXT,
|
||||||
|
response_body: DataTypes.TEXT,
|
||||||
|
response_arguments: DataTypes.TEXT,
|
||||||
|
black_list_actives: DataTypes.TEXT,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "answer",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Answer);
|
||||||
|
|
||||||
|
Answer._preCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Answer._postCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Answer._customCountingConditions = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Answer._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Answer.allowFields();
|
||||||
|
allowedFields.push(Answer._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Answer.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Answer.associate = function (models) {
|
||||||
|
Answer.belongsTo(models.question, {
|
||||||
|
foreignKey: "question_id",
|
||||||
|
as: "question",
|
||||||
|
constraints: false,
|
||||||
|
});
|
||||||
|
Answer.belongsTo(models.image, {
|
||||||
|
foreignKey: "image_id",
|
||||||
|
as: "image",
|
||||||
|
constraints: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Answer.allowFields = function () {
|
||||||
|
return ["id", "question_id", "order", "answer", "answer_value", "hide_answer", "explaination", "image_id", "response_header", "response_body", "response_arguments", "black_list_actives"];
|
||||||
|
};
|
||||||
|
|
||||||
|
Answer.labels = function () {
|
||||||
|
return ["ID", "Question ID", "Order", "Answer", "Answer value", "Hide answer", "Explaination", "Image ID", "Response header", "Response body", "Response arguments", "Black listed actives"];
|
||||||
|
};
|
||||||
|
|
||||||
|
Answer.validationRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["question_id", "Question ID", "required"],
|
||||||
|
["order", "Order", "required"],
|
||||||
|
["answer", "Answer", "required"],
|
||||||
|
["answer_value", "Answer value", ""],
|
||||||
|
["hide_answer", "Hide answer", ""],
|
||||||
|
["explaination", "Explaination", ""],
|
||||||
|
["image_id", "Image ID", ""],
|
||||||
|
["response_header", "Response header", ""],
|
||||||
|
["response_body", "Response body", ""],
|
||||||
|
["response_arguments", "Response arguments", ""],
|
||||||
|
["black_list_actives", "Black listed actives", ""],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Answer.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["question_id", "Question ID", "required"],
|
||||||
|
["order", "Order", "required"],
|
||||||
|
["answer", "Answer", "required"],
|
||||||
|
["answer_value", "Answer value", ""],
|
||||||
|
["hide_answer", "Hide answer", ""],
|
||||||
|
["explaination", "Explaination", ""],
|
||||||
|
["image_id", "Image ID", ""],
|
||||||
|
["response_header", "Response header", ""],
|
||||||
|
["response_body", "Response body", ""],
|
||||||
|
["response_arguments", "Response arguments", ""],
|
||||||
|
["black_list_actives", "Black listed actives", ""],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Answer.get_question_paginated = function (db, where = {}, ...rest) {
|
||||||
|
return Answer.getPaginated(...rest, [
|
||||||
|
{
|
||||||
|
model: db.question,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "question",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
Answer.get_image_paginated = function (db, where = {}, ...rest) {
|
||||||
|
return Answer.getPaginated(...rest, [
|
||||||
|
{
|
||||||
|
model: db.image,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "image",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
Answer.get_answer_question = (id, db) => {
|
||||||
|
return Answer.findByPk(id, {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.question,
|
||||||
|
required: false,
|
||||||
|
as: "question",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Answer.get_answer_image = (id, db) => {
|
||||||
|
return Answer.findByPk(id, {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.image,
|
||||||
|
required: false,
|
||||||
|
as: "image",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Answer.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(
|
||||||
|
[
|
||||||
|
"id",
|
||||||
|
"question_id",
|
||||||
|
"order",
|
||||||
|
"answer",
|
||||||
|
"answer_value",
|
||||||
|
"hide_answer",
|
||||||
|
"explaination",
|
||||||
|
"image_id",
|
||||||
|
"response_header",
|
||||||
|
"response_body",
|
||||||
|
"response_arguments",
|
||||||
|
"black_list_actives",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
],
|
||||||
|
Object.keys(fields)
|
||||||
|
);
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
return Answer;
|
||||||
|
};
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* configuration Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require("bcryptjs");
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require("lodash");
|
||||||
|
const coreModel = require("./../core/models");
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Configuration = sequelize.define(
|
||||||
|
"configuration",
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
image_id: DataTypes.INTEGER,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "configuration",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Configuration);
|
||||||
|
|
||||||
|
Configuration._preCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Configuration._postCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Configuration._customCountingConditions = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Configuration._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Configuration.allowFields();
|
||||||
|
allowedFields.push(Configuration._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Configuration.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Configuration.associate = function (models) {
|
||||||
|
Configuration.belongsTo(models.image, {
|
||||||
|
foreignKey: "image_id",
|
||||||
|
as: "image",
|
||||||
|
constraints: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Configuration.allowFields = function () {
|
||||||
|
return ["id", "image_id"];
|
||||||
|
};
|
||||||
|
|
||||||
|
Configuration.labels = function () {
|
||||||
|
return ["ID", "Image"];
|
||||||
|
};
|
||||||
|
|
||||||
|
Configuration.validationRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["image_id", "Image", "required"],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Configuration.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["image_id", "Image", "required"],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Configuration.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(["id", "image_id", "created_at", "updated_at"], Object.keys(fields));
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
return Configuration;
|
||||||
|
};
|
||||||
@@ -0,0 +1,208 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* credential Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require('bcryptjs');
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require('lodash');
|
||||||
|
const coreModel = require('./../core/models');
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Credential = sequelize.define(
|
||||||
|
"credential",
|
||||||
|
{
|
||||||
|
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
oauth: DataTypes.STRING,
|
||||||
|
email: DataTypes.STRING,
|
||||||
|
password: DataTypes.STRING,
|
||||||
|
user_id: DataTypes.INTEGER,
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
verify: DataTypes.INTEGER,
|
||||||
|
status: DataTypes.INTEGER,
|
||||||
|
two_factor_authentication: DataTypes.INTEGER,
|
||||||
|
force_password_change: DataTypes.BOOLEAN,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "credential",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Credential);
|
||||||
|
|
||||||
|
Credential._preCreateProcessing = function (data) {
|
||||||
|
if(!data.status) data.status = 1;
|
||||||
|
if(!data.two_factor_authentication) data.two_factor_authentication = 0;
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Credential._postCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Credential._customCountingConditions = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Credential._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Credential.allowFields();
|
||||||
|
allowedFields.push(Credential._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Credential.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Credential.associate = function(models) {
|
||||||
|
Credential.belongsTo(models.user, {
|
||||||
|
foreignKey: "user_id",
|
||||||
|
as: "user",
|
||||||
|
constraints: false,
|
||||||
|
}) };
|
||||||
|
|
||||||
|
|
||||||
|
Credential.verify_mapping = function (verify) {
|
||||||
|
const mapping = {"0":"Not verified","1":"Verified"}
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[verify];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Credential.status_mapping = function (status) {
|
||||||
|
const mapping = {"0":"Inactive","1":"Active","2":"Suspend"}
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[status];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Credential.type_mapping = function (type) {
|
||||||
|
const mapping = {"0":"normal","1":"facebook","2":"google","3":"twitter"}
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[type];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Credential.two_factor_authentication_mapping = function (two_factor_authentication) {
|
||||||
|
const mapping = {"0":"No","1":"Yes"}
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[two_factor_authentication];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Credential.allowFields = function () {
|
||||||
|
return ['id','oauth','email','password','user_id','type','verify','status','two_factor_authentication','force_password_change',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Credential.labels = function () {
|
||||||
|
return ['ID','ID','Email','Password','User','Type','Verified','Status','Two factor authentication','',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Credential.validationRules = function () {
|
||||||
|
return [
|
||||||
|
['id', 'ID', ''],
|
||||||
|
['oauth', 'ID', ''],
|
||||||
|
['email', 'Email', 'required|valid_email'],
|
||||||
|
['password', 'Password', 'required'],
|
||||||
|
['user_id', 'User', ''],
|
||||||
|
['type', 'Type', 'required'],
|
||||||
|
['verify', 'Verified', 'required'],
|
||||||
|
['status', 'Status', 'required'],
|
||||||
|
['two_factor_authentication', 'Two factor authentication', ''],
|
||||||
|
['force_password_change', '', ''],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Credential.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
['id', 'ID', ''],
|
||||||
|
['oauth', 'ID', ''],
|
||||||
|
['email', 'Email', 'required|valid_email'],
|
||||||
|
['password', 'Password', ''],
|
||||||
|
['user_id', 'User', ''],
|
||||||
|
['type', 'Type', 'required'],
|
||||||
|
['verify', 'Verified', 'required'],
|
||||||
|
['status', 'Status', 'required'],
|
||||||
|
['two_factor_authentication', 'Two factor authentication', ''],
|
||||||
|
['force_password_change', '', ''],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Credential.get_user_paginated = function(db, where = {}, ...rest) {
|
||||||
|
return Credential.getPaginated(...rest, [{
|
||||||
|
model: db.user,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "user",
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Credential.get_credential_user = (id, db) => {
|
||||||
|
return Credential.findByPk(id,
|
||||||
|
{
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.user,
|
||||||
|
required: false,
|
||||||
|
as: "user",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Credential.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(
|
||||||
|
[
|
||||||
|
'id','oauth','email','password','user_id','type','verify','status','two_factor_authentication','force_password_change','created_at','updated_at',
|
||||||
|
],
|
||||||
|
Object.keys(fields),
|
||||||
|
);
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return Credential;
|
||||||
|
};
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* email Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require('bcryptjs');
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require('lodash');
|
||||||
|
const coreModel = require('./../core/models');
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Email = sequelize.define(
|
||||||
|
"email",
|
||||||
|
{
|
||||||
|
slug: DataTypes.STRING,
|
||||||
|
subject: DataTypes.TEXT,
|
||||||
|
tag: DataTypes.TEXT,
|
||||||
|
html: DataTypes.TEXT,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "email",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Email);
|
||||||
|
|
||||||
|
Email._preCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Email._postCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Email._customCountingConditions = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Email._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Email.allowFields();
|
||||||
|
allowedFields.push(Email._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Email.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Email.associate = function(models) { };
|
||||||
|
|
||||||
|
|
||||||
|
Email.type_mapping = function (type) {
|
||||||
|
const mapping = {"0":"Forgot_token","1":"Access token","2":"Refresh_token","3":"Other","4":"Api Key","5":"Api Secret","6":"Verify"}
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[type];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Email.allowFields = function () {
|
||||||
|
return ['slug','subject','tag','html',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Email.labels = function () {
|
||||||
|
return ['Email Type','Subject','Replacement Tags','Email Body',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Email.validationRules = function () {
|
||||||
|
return [
|
||||||
|
['slug', 'Email Type', 'required|is_unique[email.slug]'],
|
||||||
|
['subject', 'Subject', 'required'],
|
||||||
|
['tag', 'Replacement Tags', 'required'],
|
||||||
|
['html', 'Email Body', 'required'],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Email.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
['slug', 'Email Type', ''],
|
||||||
|
['subject', 'Subject', 'required'],
|
||||||
|
['tag', 'Replacement Tags', ''],
|
||||||
|
['html', 'Email Body', 'required'],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Email.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(
|
||||||
|
[
|
||||||
|
'slug','subject','tag','html','created_at','updated_at',
|
||||||
|
],
|
||||||
|
Object.keys(fields),
|
||||||
|
);
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return Email;
|
||||||
|
};
|
||||||
@@ -0,0 +1,199 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* image Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require("bcryptjs");
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require("lodash");
|
||||||
|
const coreModel = require("./../core/models");
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Image = sequelize.define(
|
||||||
|
"image",
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
url: DataTypes.TEXT,
|
||||||
|
caption: DataTypes.TEXT,
|
||||||
|
user_id: DataTypes.INTEGER,
|
||||||
|
width: DataTypes.INTEGER,
|
||||||
|
height: DataTypes.INTEGER,
|
||||||
|
mobile_width: DataTypes.INTEGER,
|
||||||
|
mobile_height: DataTypes.INTEGER,
|
||||||
|
upload_type: DataTypes.INTEGER,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "image",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Image);
|
||||||
|
|
||||||
|
Image._preCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Image._postCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Image._customCountingConditions = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Image._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Image.allowFields();
|
||||||
|
allowedFields.push(Image._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Image.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Image.associate = function (models) {
|
||||||
|
Image.belongsTo(models.user, {
|
||||||
|
foreignKey: "user_id",
|
||||||
|
as: "user",
|
||||||
|
constraints: false,
|
||||||
|
});
|
||||||
|
Image.hasOne(models.configuration, {
|
||||||
|
foreignKey: "image_id",
|
||||||
|
as: "configuration",
|
||||||
|
constraints: false,
|
||||||
|
});
|
||||||
|
Image.hasMany(models.answer, {
|
||||||
|
foreignKey: "image_id",
|
||||||
|
as: "answers",
|
||||||
|
constraints: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Image.upload_type_mapping = function (upload_type) {
|
||||||
|
const mapping = { 0: "Server Hosted", 1: "External Link", 2: "S3", 3: "Cloudinary", 4: "File", 5: "External File", 6: "Local Hosted" };
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[upload_type];
|
||||||
|
};
|
||||||
|
|
||||||
|
Image.allowFields = function () {
|
||||||
|
return ["image_id", "id", "url", "caption", "user_id", "width", "height", "mobile_width", "mobile_height", "upload_type"];
|
||||||
|
};
|
||||||
|
|
||||||
|
Image.labels = function () {
|
||||||
|
return ["ID", "URL", "Caption", "User", "Width", "Height", "Mobile width", "Mobile height", "Upload Type"];
|
||||||
|
};
|
||||||
|
|
||||||
|
Image.validationRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["url", "URL", "required"],
|
||||||
|
["caption", "Caption", ""],
|
||||||
|
["user_id", "User", ""],
|
||||||
|
["width", "Width", ""],
|
||||||
|
["height", "Height", ""],
|
||||||
|
["mobile_width", "Mobile width", ""],
|
||||||
|
["mobile_height", "Mobile height", ""],
|
||||||
|
["upload_type", "Upload Type", ""],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Image.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["url", "URL", "required"],
|
||||||
|
["caption", "Caption", ""],
|
||||||
|
["user_id", "User", ""],
|
||||||
|
["width", "Width", ""],
|
||||||
|
["height", "Height", ""],
|
||||||
|
["mobile_width", "Mobile width", ""],
|
||||||
|
["mobile_height", "Mobile height", ""],
|
||||||
|
["upload_type", "Upload Type", ""],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Image.get_user_paginated = function (db, where = {}, ...rest) {
|
||||||
|
return Image.getPaginated(...rest, [
|
||||||
|
{
|
||||||
|
model: db.user,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "user",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
Image.get_answer_paginated = function (db, where = {}, ...rest) {
|
||||||
|
return Image.getPaginated(...rest, [
|
||||||
|
{
|
||||||
|
model: db.answer,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "answers",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
Image.get_image_user = (id, db) => {
|
||||||
|
return Image.findByPk(id, {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.user,
|
||||||
|
required: false,
|
||||||
|
as: "user",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Image.get_image_answer = (id, db) => {
|
||||||
|
return Image.findByPk(id, {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.answer,
|
||||||
|
required: false,
|
||||||
|
as: "answers",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Image.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(["id", "url", "caption", "user_id", "width", "height", "mobile_width", "mobile_height", "upload_type", "created_at", "updated_at"], Object.keys(fields));
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
return Image;
|
||||||
|
};
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
'use strict';
|
||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2020*/
|
||||||
|
/**
|
||||||
|
* Sequelize File
|
||||||
|
* @copyright 2020 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
let Sequelize = require('sequelize');
|
||||||
|
const basename = path.basename(__filename);
|
||||||
|
const dotenv = require('dotenv');
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
let db = {};
|
||||||
|
|
||||||
|
let sequelize = new Sequelize(process.env.DB_DATABASE, process.env.DB_USERNAME, process.env.DB_PASSWORD, {
|
||||||
|
dialect: process.env.DB_ADAPTER,
|
||||||
|
username: process.env.DB_USERNAME,
|
||||||
|
password: process.env.DB_PASSWORD,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
host: process.env.DB_HOSTNAME,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
logging: console.log,
|
||||||
|
timezone: '-04:00',
|
||||||
|
pool: {
|
||||||
|
maxConnections: 1,
|
||||||
|
minConnections: 0,
|
||||||
|
maxIdleTime: 100,
|
||||||
|
},
|
||||||
|
define: {
|
||||||
|
timestamps: false,
|
||||||
|
underscoredAll: true,
|
||||||
|
underscored: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// sequelize.sync({ force: true });
|
||||||
|
|
||||||
|
fs.readdirSync(__dirname)
|
||||||
|
.filter((file) => {
|
||||||
|
return file.indexOf('.') !== 0 && file !== basename && file.slice(-3) === '.js';
|
||||||
|
})
|
||||||
|
.forEach((file) => {
|
||||||
|
var model = sequelize['import'](path.join(__dirname, file));
|
||||||
|
db[model.name] = model;
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(db).forEach((modelName) => {
|
||||||
|
if (db[modelName].associate) {
|
||||||
|
db[modelName].associate(db);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
db.sequelize = sequelize;
|
||||||
|
db.Sequelize = Sequelize;
|
||||||
|
|
||||||
|
module.exports = db;
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* member_operation Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require('bcryptjs');
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require('lodash');
|
||||||
|
const coreModel = require('./../core/models');
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Member_operation = sequelize.define(
|
||||||
|
"member_operation",
|
||||||
|
{
|
||||||
|
action: DataTypes.STRING,
|
||||||
|
detail: DataTypes.TEXT,
|
||||||
|
last_ip: DataTypes.STRING,
|
||||||
|
user_agent: DataTypes.STRING,
|
||||||
|
status: DataTypes.INTEGER,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "member_operation",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Member_operation);
|
||||||
|
|
||||||
|
Member_operation._preCreateProcessing = function (data) {
|
||||||
|
if(!data.status) data.status = 1;
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Member_operation._postCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Member_operation._customCountingConditions = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Member_operation._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Member_operation.allowFields();
|
||||||
|
allowedFields.push(Member_operation._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Member_operation.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Member_operation.associate = function(models) {
|
||||||
|
Member_operation.belongsTo(models.user, {
|
||||||
|
foreignKey: "user_id",
|
||||||
|
as: "user",
|
||||||
|
constraints: false,
|
||||||
|
}) };
|
||||||
|
|
||||||
|
|
||||||
|
Member_operation.status_mapping = function (status) {
|
||||||
|
const mapping = {"0":"Inactive","1":"Active"}
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[status];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Member_operation.allowFields = function () {
|
||||||
|
return ["user_id",'action','detail','last_ip','user_agent','status',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Member_operation.labels = function () {
|
||||||
|
return ['Action','Detail','Last IP','User Agent','Status',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Member_operation.validationRules = function () {
|
||||||
|
return [
|
||||||
|
['action', 'Action', 'required|max[50]'],
|
||||||
|
['detail', 'Detail', 'required'],
|
||||||
|
['last_ip', 'Last IP', 'required'],
|
||||||
|
['user_agent', 'User Agent', 'required'],
|
||||||
|
['status', 'Status', 'required|integer'],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Member_operation.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
['action', 'Action', ''],
|
||||||
|
['detail', 'Detail', ''],
|
||||||
|
['last_ip', 'Last IP', ''],
|
||||||
|
['user_agent', 'User Agent', ''],
|
||||||
|
['status', 'Status', 'required|integer'],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Member_operation.get_user_paginated = function(db, where = {}, ...rest) {
|
||||||
|
return Member_operation.getPaginated(...rest, [{
|
||||||
|
model: db.user,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "user",
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Member_operation.get_member_operation_user = (id, db) => {
|
||||||
|
return Member_operation.findByPk(id,
|
||||||
|
{
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.user,
|
||||||
|
required: false,
|
||||||
|
as: "user",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Member_operation.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(
|
||||||
|
[
|
||||||
|
'action','detail','last_ip','user_agent','status','created_at','updated_at',
|
||||||
|
],
|
||||||
|
Object.keys(fields),
|
||||||
|
);
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return Member_operation;
|
||||||
|
};
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* order Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require("bcryptjs");
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require("lodash");
|
||||||
|
const coreModel = require("./../core/models");
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Order = sequelize.define(
|
||||||
|
"order",
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
webhook_id: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
unique: true,
|
||||||
|
},
|
||||||
|
shopify_id: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
unique: true,
|
||||||
|
},
|
||||||
|
event: DataTypes.TEXT,
|
||||||
|
customer_shopify_id: DataTypes.STRING,
|
||||||
|
customer: DataTypes.TEXT,
|
||||||
|
answers: DataTypes.TEXT,
|
||||||
|
profile: DataTypes.TEXT,
|
||||||
|
actives: DataTypes.TEXT,
|
||||||
|
items: DataTypes.TEXT,
|
||||||
|
financial_status: DataTypes.STRING,
|
||||||
|
fulfillment_status: DataTypes.STRING,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "order",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Order);
|
||||||
|
|
||||||
|
Order._preCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Order._postCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Order._customCountingConditions = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Order._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Order.allowFields();
|
||||||
|
allowedFields.push(Order._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Order.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Order.associate = function (models) {};
|
||||||
|
|
||||||
|
Order.allowFields = function () {
|
||||||
|
return ["id", "webhook_id", "shopify_id", "event", "profile", "actives", "customer_shopify_id", "customer", "answers", "items", "financial_status", "fulfillment_status"];
|
||||||
|
};
|
||||||
|
|
||||||
|
Order.labels = function () {
|
||||||
|
return ["ID", "Webhook Id", "Order shopify id", "Event", "Profile", "Actives", "Customer", "Customer", "Answers", "Items", "Financial status", "Fulfillment status"];
|
||||||
|
};
|
||||||
|
|
||||||
|
Order.validationRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["shopify_id", "Order shopify id", ""],
|
||||||
|
["event", "Event", ""],
|
||||||
|
["customer_shopify_id", "Customer", ""],
|
||||||
|
["customer", "Customer", ""],
|
||||||
|
["answers", "Answers", ""],
|
||||||
|
["items", "Items", ""],
|
||||||
|
["financial_status", "Financial status", ""],
|
||||||
|
["fulfillment_status", "Fulfillment status", ""],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Order.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["shopify_id", "Order shopify id", ""],
|
||||||
|
["event", "Event", ""],
|
||||||
|
["customer_shopify_id", "Customer", ""],
|
||||||
|
["customer", "Customer", ""],
|
||||||
|
["answers", "Answers", ""],
|
||||||
|
["items", "Items", ""],
|
||||||
|
["financial_status", "Financial status", ""],
|
||||||
|
["fulfillment_status", "Fulfillment status", ""],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Order.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(
|
||||||
|
["id", "webhook_id", "shopify_id", "event", "customer_shopify_id", "profile", "actives", "customer", "answers", "items", "financial_status", "fulfillment_status", "created_at", "updated_at"],
|
||||||
|
Object.keys(fields)
|
||||||
|
);
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
return Order;
|
||||||
|
};
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* output_variable Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require("bcryptjs");
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require("lodash");
|
||||||
|
const coreModel = require("./../core/models");
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Output_variable = sequelize.define(
|
||||||
|
"output_variable",
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
name: DataTypes.STRING,
|
||||||
|
priority: DataTypes.FLOAT,
|
||||||
|
active_list: DataTypes.TEXT,
|
||||||
|
ranges_response: DataTypes.TEXT,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "output_variable",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Output_variable);
|
||||||
|
|
||||||
|
Output_variable._preCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Output_variable._postCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Output_variable._customCountingConditions = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Output_variable._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Output_variable.allowFields();
|
||||||
|
allowedFields.push(Output_variable._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Output_variable.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Output_variable.associate = function (models) {};
|
||||||
|
|
||||||
|
Output_variable.allowFields = function () {
|
||||||
|
return ["id", "name", "priority", "active_list", "ranges_response"];
|
||||||
|
};
|
||||||
|
|
||||||
|
Output_variable.labels = function () {
|
||||||
|
return ["ID", "Name", "Priority", "Actives list", "Ranges responses"];
|
||||||
|
};
|
||||||
|
|
||||||
|
Output_variable.validationRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["name", "Name", "required"],
|
||||||
|
["priority", "Priority", "required"],
|
||||||
|
["active_list", "Actives list", "required"],
|
||||||
|
["ranges_response", "Ranges responses", "required"],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Output_variable.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["name", "Name", "required"],
|
||||||
|
["priority", "Priority", "required"],
|
||||||
|
["active_list", "Actives list", "required"],
|
||||||
|
["ranges_response", "Ranges responses", "required"],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Output_variable.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(["id", "name", "priority", "active_list", "ranges_response", "created_at", "updated_at"], Object.keys(fields));
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
return Output_variable;
|
||||||
|
};
|
||||||
@@ -0,0 +1,304 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* question Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require("bcryptjs");
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require("lodash");
|
||||||
|
const coreModel = require("./../core/models");
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Question = sequelize.define(
|
||||||
|
"question",
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
quiz_id: DataTypes.INTEGER,
|
||||||
|
question: DataTypes.TEXT,
|
||||||
|
question_arguments: DataTypes.TEXT,
|
||||||
|
order: DataTypes.INTEGER,
|
||||||
|
image_width: DataTypes.FLOAT,
|
||||||
|
image_height: DataTypes.FLOAT,
|
||||||
|
placeholder: DataTypes.STRING,
|
||||||
|
note: DataTypes.TEXT,
|
||||||
|
note_type: DataTypes.INTEGER,
|
||||||
|
target: DataTypes.INTEGER,
|
||||||
|
response: DataTypes.TEXT,
|
||||||
|
save_response_into: DataTypes.STRING,
|
||||||
|
depends_on: DataTypes.STRING,
|
||||||
|
slider_range: DataTypes.STRING,
|
||||||
|
output_variable_name: DataTypes.STRING,
|
||||||
|
weight: DataTypes.FLOAT,
|
||||||
|
extra_output_variable: DataTypes.TEXT,
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "question",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Question);
|
||||||
|
|
||||||
|
Question._preCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Question._postCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Question._customCountingConditions = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Question._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Question.allowFields();
|
||||||
|
allowedFields.push(Question._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Question.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Question.associate = function (models) {
|
||||||
|
Question.belongsTo(models.quiz, {
|
||||||
|
foreignKey: "quiz_id",
|
||||||
|
as: "quiz",
|
||||||
|
constraints: false,
|
||||||
|
});
|
||||||
|
Question.hasMany(models.answer, {
|
||||||
|
foreignKey: "question_id",
|
||||||
|
as: "answers",
|
||||||
|
constraints: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Question.type_mapping = function (type) {
|
||||||
|
const mapping = { 1: "text", 2: "number", 3: "date", 4: "mcq", 5: "mcqi", 6: "slide", 7: "selection", 8: "geolocation" };
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[type];
|
||||||
|
};
|
||||||
|
|
||||||
|
Question.target_mapping = function (target) {
|
||||||
|
const mapping = { 1: "female", 2: "male", 3: "non-binary", 4: "all" };
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[target];
|
||||||
|
};
|
||||||
|
|
||||||
|
Question.note_type_mapping = function (note_type) {
|
||||||
|
const mapping = { 1: "Note", 2: "Scientific note" };
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[note_type];
|
||||||
|
};
|
||||||
|
|
||||||
|
Question.allowFields = function () {
|
||||||
|
return [
|
||||||
|
"question_id",
|
||||||
|
"id",
|
||||||
|
"quiz_id",
|
||||||
|
"question",
|
||||||
|
"question_arguments",
|
||||||
|
"order",
|
||||||
|
"image_width",
|
||||||
|
"image_height",
|
||||||
|
"placeholder",
|
||||||
|
"note",
|
||||||
|
"note_type",
|
||||||
|
"target",
|
||||||
|
"response",
|
||||||
|
"save_response_into",
|
||||||
|
"depends_on",
|
||||||
|
"slider_range",
|
||||||
|
"output_variable_name",
|
||||||
|
"weight",
|
||||||
|
"extra_output_variable",
|
||||||
|
"type",
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Question.labels = function () {
|
||||||
|
return [
|
||||||
|
"ID",
|
||||||
|
"Quiz ID",
|
||||||
|
"Question",
|
||||||
|
"Question arguments",
|
||||||
|
"Order",
|
||||||
|
"Image width",
|
||||||
|
"Image height",
|
||||||
|
"Placeholder",
|
||||||
|
"Note",
|
||||||
|
"Note type",
|
||||||
|
"Target",
|
||||||
|
"Response",
|
||||||
|
"Save response",
|
||||||
|
"Depends on question",
|
||||||
|
"Slider range",
|
||||||
|
"Output variable",
|
||||||
|
"weight",
|
||||||
|
"Extra output variables",
|
||||||
|
"Type",
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Question.validationRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["quiz_id", "Quiz ID", "required"],
|
||||||
|
["question", "Question", "required"],
|
||||||
|
["question_arguments", "Question arguments", ""],
|
||||||
|
["order", "Order", "required"],
|
||||||
|
["image_width", "Image width", "required"],
|
||||||
|
["image_height", "Image height", "required"],
|
||||||
|
["placeholder", "Placeholder", ""],
|
||||||
|
["note", "Note", ""],
|
||||||
|
["note_type", "Note type", ""],
|
||||||
|
["target", "Target", ""],
|
||||||
|
["response", "Response", ""],
|
||||||
|
["save_response_into", "Save response", ""],
|
||||||
|
["depends_on", "Depends on question", ""],
|
||||||
|
["slider_range", "Slider range", ""],
|
||||||
|
["output_variable_name", "Output variable", "required"],
|
||||||
|
["weight", "weight", "required"],
|
||||||
|
["extra_output_variable", "Extra output variables", ""],
|
||||||
|
["type", "Type", "required"],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Question.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["quiz_id", "Quiz ID", "required"],
|
||||||
|
["question", "Question", "required"],
|
||||||
|
["question_arguments", "Question arguments", ""],
|
||||||
|
["order", "Order", "required"],
|
||||||
|
["image_width", "Image width", "required"],
|
||||||
|
["image_height", "Image height", "required"],
|
||||||
|
["placeholder", "Placeholder", ""],
|
||||||
|
["note", "Note", ""],
|
||||||
|
["note_type", "Note type", ""],
|
||||||
|
["target", "Target", ""],
|
||||||
|
["response", "Response", ""],
|
||||||
|
["save_response_into", "Save response", ""],
|
||||||
|
["depends_on", "Depends on question", ""],
|
||||||
|
["slider_range", "Slider range", ""],
|
||||||
|
["output_variable_name", "Output variable", "required"],
|
||||||
|
["weight", "weight", "required"],
|
||||||
|
["extra_output_variable", "Extra output variables", ""],
|
||||||
|
["type", "Type", "required"],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Question.get_quiz_paginated = function (db, where = {}, ...rest) {
|
||||||
|
return Question.getPaginated(...rest, [
|
||||||
|
{
|
||||||
|
model: db.quiz,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "quiz",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
Question.get_answer_paginated = function (db, where = {}, ...rest) {
|
||||||
|
return Question.getPaginated(...rest, [
|
||||||
|
{
|
||||||
|
model: db.answer,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "answers",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
Question.get_question_quiz = (id, db) => {
|
||||||
|
return Question.findByPk(id, {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.quiz,
|
||||||
|
required: false,
|
||||||
|
as: "quiz",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Question.get_question_answer = (id, db) => {
|
||||||
|
return Question.findByPk(id, {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.answer,
|
||||||
|
required: false,
|
||||||
|
as: "answers",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Question.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(
|
||||||
|
[
|
||||||
|
"id",
|
||||||
|
"quiz_id",
|
||||||
|
"question",
|
||||||
|
"question_arguments",
|
||||||
|
"order",
|
||||||
|
"image_width",
|
||||||
|
"image_height",
|
||||||
|
"placeholder",
|
||||||
|
"note",
|
||||||
|
"note_type",
|
||||||
|
"target",
|
||||||
|
"response",
|
||||||
|
"save_response_into",
|
||||||
|
"depends_on",
|
||||||
|
"slider_range",
|
||||||
|
"output_variable_name",
|
||||||
|
"weight",
|
||||||
|
"extra_output_variable",
|
||||||
|
"type",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
],
|
||||||
|
Object.keys(fields)
|
||||||
|
);
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
return Question;
|
||||||
|
};
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* quiz Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require('bcryptjs');
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require('lodash');
|
||||||
|
const coreModel = require('./../core/models');
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Quiz = sequelize.define(
|
||||||
|
"quiz",
|
||||||
|
{
|
||||||
|
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
name: DataTypes.STRING,
|
||||||
|
description: DataTypes.TEXT,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "quiz",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Quiz);
|
||||||
|
|
||||||
|
Quiz._preCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Quiz._postCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Quiz._customCountingConditions = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Quiz._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Quiz.allowFields();
|
||||||
|
allowedFields.push(Quiz._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Quiz.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Quiz.associate = function(models) {
|
||||||
|
Quiz.hasMany(models.question, {
|
||||||
|
foreignKey: "quiz_id",
|
||||||
|
as: "questions",
|
||||||
|
constraints: false,
|
||||||
|
}) };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Quiz.allowFields = function () {
|
||||||
|
return ["quiz_id",'id','name','description',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Quiz.labels = function () {
|
||||||
|
return ['ID','Name','Description',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Quiz.validationRules = function () {
|
||||||
|
return [
|
||||||
|
['id', 'ID', ''],
|
||||||
|
['name', 'Name', 'required'],
|
||||||
|
['description', 'Description', ''],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Quiz.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
['id', 'ID', ''],
|
||||||
|
['name', 'Name', 'required'],
|
||||||
|
['description', 'Description', ''],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Quiz.get_question_paginated = function(db, where = {}, ...rest) {
|
||||||
|
return Quiz.getPaginated(...rest, [{
|
||||||
|
model: db.question,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "questions",
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Quiz.get_quiz_question = (id, db) => {
|
||||||
|
return Quiz.findByPk(id,
|
||||||
|
{
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.question,
|
||||||
|
required: false,
|
||||||
|
as: "questions",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Quiz.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(
|
||||||
|
[
|
||||||
|
'id','name','description','created_at','updated_at',
|
||||||
|
],
|
||||||
|
Object.keys(fields),
|
||||||
|
);
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return Quiz;
|
||||||
|
};
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* refer_log Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require('bcryptjs');
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require('lodash');
|
||||||
|
const coreModel = require('./../core/models');
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Refer_log = sequelize.define(
|
||||||
|
"refer_log",
|
||||||
|
{
|
||||||
|
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
user_id: DataTypes.INTEGER,
|
||||||
|
referrer_user_id: DataTypes.INTEGER,
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "refer_log",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Refer_log);
|
||||||
|
|
||||||
|
Refer_log._preCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Refer_log._postCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Refer_log._customCountingConditions = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Refer_log._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Refer_log.allowFields();
|
||||||
|
allowedFields.push(Refer_log._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Refer_log.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Refer_log.associate = function(models) {
|
||||||
|
Refer_log.belongsTo(models.user, {
|
||||||
|
foreignKey: "user_id",
|
||||||
|
as: "user",
|
||||||
|
constraints: false,
|
||||||
|
}) };
|
||||||
|
|
||||||
|
|
||||||
|
Refer_log.type_mapping = function (type) {
|
||||||
|
const mapping = {"0":"user"}
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[type];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Refer_log.allowFields = function () {
|
||||||
|
return ['id','user_id','referrer_user_id','type',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Refer_log.labels = function () {
|
||||||
|
return ['ID','Referree User','Referrer User','Type',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Refer_log.validationRules = function () {
|
||||||
|
return [
|
||||||
|
['id', 'ID', ''],
|
||||||
|
['user_id', 'Referree User', 'required|integer'],
|
||||||
|
['referrer_user_id', 'Referrer User', 'required|integer'],
|
||||||
|
['type', 'Type', 'required|integer'],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Refer_log.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
['id', 'ID', ''],
|
||||||
|
['user_id', 'Referree User', ''],
|
||||||
|
['referrer_user_id', 'Referrer User', ''],
|
||||||
|
['type', 'Type', 'required|integer'],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Refer_log.get_user_paginated = function(db, where = {}, ...rest) {
|
||||||
|
return Refer_log.getPaginated(...rest, [{
|
||||||
|
model: db.user,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "user",
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Refer_log.get_refer_log_user = (id, db) => {
|
||||||
|
return Refer_log.findByPk(id,
|
||||||
|
{
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.user,
|
||||||
|
required: false,
|
||||||
|
as: "user",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Refer_log.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(
|
||||||
|
[
|
||||||
|
'id','user_id','referrer_user_id','type','created_at','updated_at',
|
||||||
|
],
|
||||||
|
Object.keys(fields),
|
||||||
|
);
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return Refer_log;
|
||||||
|
};
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* result_profile Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require("bcryptjs");
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require("lodash");
|
||||||
|
const coreModel = require("./../core/models");
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Result_profile = sequelize.define(
|
||||||
|
"result_profile",
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
section_title: DataTypes.STRING,
|
||||||
|
output_variable_list: DataTypes.TEXT,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "result_profile",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Result_profile);
|
||||||
|
|
||||||
|
Result_profile._preCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Result_profile._postCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Result_profile._customCountingConditions = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Result_profile._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Result_profile.allowFields();
|
||||||
|
allowedFields.push(Result_profile._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Result_profile.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Result_profile.associate = function (models) {};
|
||||||
|
|
||||||
|
Result_profile.allowFields = function () {
|
||||||
|
return ["id", "section_title", "output_variable_list"];
|
||||||
|
};
|
||||||
|
|
||||||
|
Result_profile.labels = function () {
|
||||||
|
return ["ID", "Section title", "Variables List"];
|
||||||
|
};
|
||||||
|
|
||||||
|
Result_profile.validationRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["section_title", "Section title", ""],
|
||||||
|
["output_variable_list", "Variables List", ""],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Result_profile.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["section_title", "Section title", ""],
|
||||||
|
["output_variable_list", "Variables List", ""],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Result_profile.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(["id", "section_title", "output_variable_list", "created_at", "updated_at"], Object.keys(fields));
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
return Result_profile;
|
||||||
|
};
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* role Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require('bcryptjs');
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require('lodash');
|
||||||
|
const coreModel = require('./../core/models');
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Role = sequelize.define(
|
||||||
|
"role",
|
||||||
|
{
|
||||||
|
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
name: DataTypes.STRING,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "role",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Role);
|
||||||
|
|
||||||
|
Role._preCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Role._postCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Role._customCountingConditions = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Role._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Role.allowFields();
|
||||||
|
allowedFields.push(Role._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Role.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Role.associate = function(models) {
|
||||||
|
Role.hasMany(models.user, {
|
||||||
|
foreignKey: "user_id",
|
||||||
|
as: "users",
|
||||||
|
constraints: false,
|
||||||
|
}) };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Role.allowFields = function () {
|
||||||
|
return ["user_id",'id','name',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Role.labels = function () {
|
||||||
|
return ['ID','Role Name',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Role.validationRules = function () {
|
||||||
|
return [
|
||||||
|
['id', 'ID', ''],
|
||||||
|
['name', 'Role Name', 'required'],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Role.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
['id', 'ID', ''],
|
||||||
|
['name', 'Role Name', 'required'],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Role.get_user_paginated = function(db, where = {}, ...rest) {
|
||||||
|
return Role.getPaginated(...rest, [{
|
||||||
|
model: db.user,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "users",
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Role.get_role_user = (id, db) => {
|
||||||
|
return Role.findByPk(id,
|
||||||
|
{
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.user,
|
||||||
|
required: false,
|
||||||
|
as: "users",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Role.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(
|
||||||
|
[
|
||||||
|
'id','name','created_at','updated_at',
|
||||||
|
],
|
||||||
|
Object.keys(fields),
|
||||||
|
);
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return Role;
|
||||||
|
};
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* rule Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require("bcryptjs");
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require("lodash");
|
||||||
|
const coreModel = require("./../core/models");
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Rule = sequelize.define(
|
||||||
|
"rule",
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
output_variable_name: DataTypes.STRING,
|
||||||
|
actives: DataTypes.TEXT,
|
||||||
|
operator: DataTypes.INTEGER,
|
||||||
|
compare_value: DataTypes.FLOAT,
|
||||||
|
min: DataTypes.FLOAT,
|
||||||
|
max: DataTypes.FLOAT,
|
||||||
|
action: DataTypes.INTEGER,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "rule",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Rule);
|
||||||
|
|
||||||
|
Rule._preCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Rule._postCreateProcessing = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Rule._customCountingConditions = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Rule._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Rule.allowFields();
|
||||||
|
allowedFields.push(Rule._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Rule.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Rule.associate = function (models) {};
|
||||||
|
|
||||||
|
Rule.operator_mapping = function (operator) {
|
||||||
|
const mapping = { 0: "=:equal", 1: "<:less than", 2: "<=:less than or equal", 3: ">:greater than", 4: ">=:greater than or equal", 5: "!=:not equal", 6: "in:between" };
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[operator];
|
||||||
|
};
|
||||||
|
|
||||||
|
Rule.action_mapping = function (action) {
|
||||||
|
const mapping = { 1: "add", 2: "remove" };
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[action];
|
||||||
|
};
|
||||||
|
|
||||||
|
Rule.allowFields = function () {
|
||||||
|
return ["id", "output_variable_name", "actives", "operator", "compare_value", "min", "max", "action"];
|
||||||
|
};
|
||||||
|
|
||||||
|
Rule.labels = function () {
|
||||||
|
return ["ID", "Output variable", "actives", "Condition operator", "Compare value", "Between Min", "Between Max", "Action"];
|
||||||
|
};
|
||||||
|
|
||||||
|
Rule.validationRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["output_variable_name", "Output variable", "required"],
|
||||||
|
["actives", "actives", "required"],
|
||||||
|
["operator", "Condition operator", "required"],
|
||||||
|
["compare_value", "Compare value", "required"],
|
||||||
|
["min", "Between Min", ""],
|
||||||
|
["max", "Between Max", ""],
|
||||||
|
["action", "Action", "required"],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Rule.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
["id", "ID", ""],
|
||||||
|
["output_variable_name", "Output variable", "required"],
|
||||||
|
["actives", "actives", "required"],
|
||||||
|
["operator", "Condition operator", "required"],
|
||||||
|
["compare_value", "Compare value", "required"],
|
||||||
|
["min", "Between Min", ""],
|
||||||
|
["max", "Between Max", ""],
|
||||||
|
["action", "Action", "required"],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Rule.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(["id", "output_variable_name", "actives", "operator", "compare_value", "min", "max", "action", "created_at", "updated_at"], Object.keys(fields));
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
return Rule;
|
||||||
|
};
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* setting Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require('bcryptjs');
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require('lodash');
|
||||||
|
const coreModel = require('./../core/models');
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Setting = sequelize.define(
|
||||||
|
"setting",
|
||||||
|
{
|
||||||
|
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
key: DataTypes.STRING,
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
value: DataTypes.TEXT,
|
||||||
|
maintenance: DataTypes.INTEGER,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "setting",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Setting);
|
||||||
|
|
||||||
|
Setting._preCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Setting._postCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Setting._customCountingConditions = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Setting._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Setting.allowFields();
|
||||||
|
allowedFields.push(Setting._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Setting.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Setting.associate = function(models) { };
|
||||||
|
|
||||||
|
|
||||||
|
Setting.type_mapping = function (type) {
|
||||||
|
const mapping = {"0":"text","1":"select","2":"number","3":"image","4":"read_only"}
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[type];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Setting.maintenance_mapping = function (maintenance) {
|
||||||
|
const mapping = {"0":"No","1":"Yes"}
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[maintenance];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Setting.allowFields = function () {
|
||||||
|
return ['id','key','type','value','maintenance',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Setting.labels = function () {
|
||||||
|
return ['ID','Setting Field','Setting Type','Setting Value','Setting Type',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Setting.validationRules = function () {
|
||||||
|
return [
|
||||||
|
['id', 'ID', ''],
|
||||||
|
['key', 'Setting Field', 'required'],
|
||||||
|
['type', 'Setting Type', 'required'],
|
||||||
|
['value', 'Setting Value', 'required'],
|
||||||
|
['maintenance', 'Setting Type', 'required'],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Setting.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
['id', 'ID', ''],
|
||||||
|
['key', 'Setting Field', ''],
|
||||||
|
['type', 'Setting Type', ''],
|
||||||
|
['value', 'Setting Value', 'required'],
|
||||||
|
['maintenance', 'Setting Type', ''],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Setting.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(
|
||||||
|
[
|
||||||
|
'id','key','type','value','maintenance','created_at','updated_at',
|
||||||
|
],
|
||||||
|
Object.keys(fields),
|
||||||
|
);
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return Setting;
|
||||||
|
};
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* sms Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require('bcryptjs');
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require('lodash');
|
||||||
|
const coreModel = require('./../core/models');
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Sms = sequelize.define(
|
||||||
|
"sms",
|
||||||
|
{
|
||||||
|
slug: DataTypes.STRING,
|
||||||
|
tag: DataTypes.TEXT,
|
||||||
|
content: DataTypes.TEXT,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "sms",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Sms);
|
||||||
|
|
||||||
|
Sms._preCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Sms._postCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Sms._customCountingConditions = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Sms._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Sms.allowFields();
|
||||||
|
allowedFields.push(Sms._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Sms.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Sms.associate = function(models) { };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Sms.allowFields = function () {
|
||||||
|
return ['slug','tag','content',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Sms.labels = function () {
|
||||||
|
return ['SMS Slug','Replacement Tags','SMS Body',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Sms.validationRules = function () {
|
||||||
|
return [
|
||||||
|
['slug', 'SMS Slug', 'required|is_unique[sms.slug]'],
|
||||||
|
['tag', 'Replacement Tags', 'required'],
|
||||||
|
['content', 'SMS Body', 'required'],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Sms.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
['slug', 'SMS Slug', ''],
|
||||||
|
['tag', 'Replacement Tags', ''],
|
||||||
|
['content', 'SMS Body', 'required'],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Sms.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(
|
||||||
|
[
|
||||||
|
'slug','tag','content','created_at','updated_at',
|
||||||
|
],
|
||||||
|
Object.keys(fields),
|
||||||
|
);
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return Sms;
|
||||||
|
};
|
||||||
@@ -0,0 +1,187 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* token Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require('bcryptjs');
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require('lodash');
|
||||||
|
const coreModel = require('./../core/models');
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Token = sequelize.define(
|
||||||
|
"token",
|
||||||
|
{
|
||||||
|
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
token: DataTypes.TEXT,
|
||||||
|
data: DataTypes.TEXT,
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
user_id: DataTypes.INTEGER,
|
||||||
|
ttl: DataTypes.INTEGER,
|
||||||
|
issue_at: DataTypes.DATE,
|
||||||
|
expire_at: DataTypes.DATE,
|
||||||
|
status: DataTypes.INTEGER,
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: false,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "token",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, Token);
|
||||||
|
|
||||||
|
Token._preCreateProcessing = function (data) {
|
||||||
|
if(!data.status) data.status = 1;
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Token._postCreateProcessing = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
Token._customCountingConditions = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Token._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = Token.allowFields();
|
||||||
|
allowedFields.push(Token._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
Token.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
Token.associate = function(models) {
|
||||||
|
Token.belongsTo(models.user, {
|
||||||
|
foreignKey: "user_id",
|
||||||
|
as: "user",
|
||||||
|
constraints: false,
|
||||||
|
}) };
|
||||||
|
|
||||||
|
|
||||||
|
Token.status_mapping = function (status) {
|
||||||
|
const mapping = {"0":"Inactive","1":"Active"}
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[status];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Token.type_mapping = function (type) {
|
||||||
|
const mapping = {"0":"Forgot_token","1":"Access token","2":"Refresh_token","3":"Other","4":"Api Key","5":"Api Secret","6":"Verify"}
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[type];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Token.allowFields = function () {
|
||||||
|
return ['id','token','data','type','user_id','ttl','issue_at','expire_at','status',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Token.labels = function () {
|
||||||
|
return ['ID','Token','Data','Token Type','User','Time To Live','Issue at','Expire at','Status',];
|
||||||
|
};
|
||||||
|
|
||||||
|
Token.validationRules = function () {
|
||||||
|
return [
|
||||||
|
['id', 'ID', ''],
|
||||||
|
['token', 'Token', 'required'],
|
||||||
|
['data', 'Data', 'required'],
|
||||||
|
['type', 'Token Type', 'required|integer'],
|
||||||
|
['user_id', 'User', 'required|integer'],
|
||||||
|
['ttl', 'Time To Live', 'required|integer'],
|
||||||
|
['issue_at', 'Issue at', 'required'],
|
||||||
|
['expire_at', 'Expire at', 'required'],
|
||||||
|
['status', 'Status', 'required|integer'],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
Token.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
['id', 'ID', ''],
|
||||||
|
['token', 'Token', 'required'],
|
||||||
|
['data', 'Data', 'required'],
|
||||||
|
['type', 'Token Type', 'required|integer'],
|
||||||
|
['user_id', 'User', 'required|integer'],
|
||||||
|
['ttl', 'Time To Live', 'required|integer'],
|
||||||
|
['issue_at', 'Issue at', 'required'],
|
||||||
|
['expire_at', 'Expire at', 'required'],
|
||||||
|
['status', 'Status', 'required|integer'],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Token.get_user_paginated = function(db, where = {}, ...rest) {
|
||||||
|
return Token.getPaginated(...rest, [{
|
||||||
|
model: db.user,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "user",
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Token.get_token_user = (id, db) => {
|
||||||
|
return Token.findByPk(id,
|
||||||
|
{
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.user,
|
||||||
|
required: false,
|
||||||
|
as: "user",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// ex
|
||||||
|
Token.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(
|
||||||
|
[
|
||||||
|
'id','token','data','type','user_id','ttl','issue_at','expire_at','status','created_at','updated_at',
|
||||||
|
],
|
||||||
|
Object.keys(fields),
|
||||||
|
);
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return Token;
|
||||||
|
};
|
||||||
@@ -0,0 +1,357 @@
|
|||||||
|
/*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/
|
||||||
|
/**
|
||||||
|
* user Model
|
||||||
|
* @copyright 2021 Manaknightdigital Inc.
|
||||||
|
* @link https://manaknightdigital.com
|
||||||
|
* @license Proprietary Software licensing
|
||||||
|
* @author Ryan Wong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const moment = require("moment");
|
||||||
|
const bcrypt = require('bcryptjs');
|
||||||
|
const { Op } = require("sequelize");
|
||||||
|
const { intersection } = require('lodash');
|
||||||
|
const coreModel = require('./../core/models');
|
||||||
|
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const User = sequelize.define(
|
||||||
|
"user",
|
||||||
|
{
|
||||||
|
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
role_id: DataTypes.INTEGER,
|
||||||
|
profile_id: DataTypes.INTEGER,
|
||||||
|
organization_id: DataTypes.INTEGER,
|
||||||
|
first_name: DataTypes.STRING,
|
||||||
|
last_name: DataTypes.STRING,
|
||||||
|
phone: DataTypes.STRING,
|
||||||
|
image: DataTypes.TEXT,
|
||||||
|
refer: DataTypes.STRING,
|
||||||
|
stripe_uid: DataTypes.STRING,
|
||||||
|
paypal_uid: DataTypes.STRING,
|
||||||
|
expire_at: DataTypes.DATEONLY,
|
||||||
|
status: DataTypes.INTEGER,
|
||||||
|
created_at: DataTypes.DATEONLY,
|
||||||
|
updated_at: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true,
|
||||||
|
freezeTableName: true,
|
||||||
|
tableName: "user",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
underscoredAll: false,
|
||||||
|
underscored: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
coreModel.call(this, User);
|
||||||
|
|
||||||
|
User._preCreateProcessing = function (data) {
|
||||||
|
if(!data.image) data.image = "/image/profile.png";
|
||||||
|
if(!data.refer) data.refer = Math.round(Math.random() * 1000000000000,0);
|
||||||
|
if(!data.status) data.status = 1;
|
||||||
|
if(!data.verify) data.verify = 0;
|
||||||
|
if(!data.type)
|
||||||
|
{
|
||||||
|
data.type = 'n';
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
User._postCreateProcessing = function (data) {
|
||||||
|
if(data.password && data.password.length < 1)
|
||||||
|
{
|
||||||
|
delete data.password;
|
||||||
|
}
|
||||||
|
if(data.image && data.image.length < 1)
|
||||||
|
{
|
||||||
|
delete data.image;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
User._customCountingConditions = function (data) {
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
User._filterAllowKeys = function (data) {
|
||||||
|
let cleanData = {};
|
||||||
|
let allowedFields = User.allowFields();
|
||||||
|
allowedFields.push(User._primaryKey());
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
if (allowedFields.includes(key)) {
|
||||||
|
cleanData[key] = data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cleanData;
|
||||||
|
};
|
||||||
|
|
||||||
|
User.timeDefaultMapping = function () {
|
||||||
|
let results = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
for (let j = 0; j < 60; j++) {
|
||||||
|
let hour = i < 10 ? "0".i : i;
|
||||||
|
let min = j < 10 ? "0".j : j;
|
||||||
|
results[i * 60 + j] = `${hour}:${min}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
User.associate = function(models) {
|
||||||
|
User.belongsTo(models.role, {
|
||||||
|
foreignKey: "role_id",
|
||||||
|
as: "role",
|
||||||
|
constraints: false,
|
||||||
|
})
|
||||||
|
User.hasOne(models.credential, {
|
||||||
|
foreignKey: "user_id",
|
||||||
|
as: "credential",
|
||||||
|
constraints: false,
|
||||||
|
})
|
||||||
|
User.hasMany(models.refer_log, {
|
||||||
|
foreignKey: "user_id",
|
||||||
|
as: "refer_logs",
|
||||||
|
constraints: false,
|
||||||
|
})
|
||||||
|
User.hasMany(models.member_operation, {
|
||||||
|
foreignKey: "user_id",
|
||||||
|
as: "member_operations",
|
||||||
|
constraints: false,
|
||||||
|
})
|
||||||
|
User.hasMany(models.admin_operation, {
|
||||||
|
foreignKey: "user_id",
|
||||||
|
as: "admin_operations",
|
||||||
|
constraints: false,
|
||||||
|
})
|
||||||
|
User.hasMany(models.token, {
|
||||||
|
foreignKey: "user_id",
|
||||||
|
as: "tokens",
|
||||||
|
constraints: false,
|
||||||
|
})
|
||||||
|
User.hasMany(models.image, {
|
||||||
|
foreignKey: "user_id",
|
||||||
|
as: "images",
|
||||||
|
constraints: false,
|
||||||
|
}) };
|
||||||
|
|
||||||
|
|
||||||
|
User.status_mapping = function (status) {
|
||||||
|
const mapping = {"0":"Inactive","1":"Active","2":"Suspend"}
|
||||||
|
|
||||||
|
if (arguments.length === 0) return mapping;
|
||||||
|
else return mapping[status];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
User.allowFields = function () {
|
||||||
|
return ["user_id","user_id","user_id","user_id","user_id","user_id",'id','role_id','profile_id','organization_id','first_name','last_name','phone','image','refer','stripe_uid','paypal_uid','expire_at','status',];
|
||||||
|
};
|
||||||
|
|
||||||
|
User.labels = function () {
|
||||||
|
return ['ID','Role ID','Profile ID','Organization ID','First Name','Last Name','Phone #','Image','Refer Code','Stripe ID','PayPal ID','Expire At','Status',];
|
||||||
|
};
|
||||||
|
|
||||||
|
User.validationRules = function () {
|
||||||
|
return [
|
||||||
|
['id', 'ID', ''],
|
||||||
|
['role_id', 'Role ID', ''],
|
||||||
|
['profile_id', 'Profile ID', ''],
|
||||||
|
['organization_id', 'Organization ID', ''],
|
||||||
|
['first_name', 'First Name', 'required'],
|
||||||
|
['last_name', 'Last Name', 'required'],
|
||||||
|
['phone', 'Phone #', ''],
|
||||||
|
['image', 'Image', ''],
|
||||||
|
['refer', 'Refer Code', ''],
|
||||||
|
['stripe_uid', 'Stripe ID', ''],
|
||||||
|
['paypal_uid', 'PayPal ID', ''],
|
||||||
|
['expire_at', 'Expire At', ''],
|
||||||
|
['status', 'Status', 'required'],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
User.validationEditRules = function () {
|
||||||
|
return [
|
||||||
|
['id', 'ID', ''],
|
||||||
|
['role_id', 'Role ID', ''],
|
||||||
|
['profile_id', 'Profile ID', ''],
|
||||||
|
['organization_id', 'Organization ID', ''],
|
||||||
|
['first_name', 'First Name', ''],
|
||||||
|
['last_name', 'Last Name', ''],
|
||||||
|
['phone', 'Phone #', ''],
|
||||||
|
['image', 'Image', ''],
|
||||||
|
['refer', 'Refer Code', ''],
|
||||||
|
['stripe_uid', 'Stripe ID', ''],
|
||||||
|
['paypal_uid', 'PayPal ID', ''],
|
||||||
|
['expire_at', 'Expire At', ''],
|
||||||
|
['status', 'Status', ''],
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
User.get_role_paginated = function(db, where = {}, ...rest) {
|
||||||
|
return User.getPaginated(...rest, [{
|
||||||
|
model: db.role,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "role",
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
User.get_credential_paginated = function(db, where = {}, ...rest) {
|
||||||
|
return User.getPaginated(...rest, [{
|
||||||
|
model: db.credential,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "credential",
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
User.get_refer_log_paginated = function(db, where = {}, ...rest) {
|
||||||
|
return User.getPaginated(...rest, [{
|
||||||
|
model: db.refer_log,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "refer_logs",
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
User.get_member_operation_paginated = function(db, where = {}, ...rest) {
|
||||||
|
return User.getPaginated(...rest, [{
|
||||||
|
model: db.member_operation,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "member_operations",
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
User.get_admin_operation_paginated = function(db, where = {}, ...rest) {
|
||||||
|
return User.getPaginated(...rest, [{
|
||||||
|
model: db.admin_operation,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "admin_operations",
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
User.get_token_paginated = function(db, where = {}, ...rest) {
|
||||||
|
return User.getPaginated(...rest, [{
|
||||||
|
model: db.token,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "tokens",
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
User.get_image_paginated = function(db, where = {}, ...rest) {
|
||||||
|
return User.getPaginated(...rest, [{
|
||||||
|
model: db.image,
|
||||||
|
where: where,
|
||||||
|
required: Object.keys(where).length > 0 ? true : false,
|
||||||
|
as: "images",
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
User.get_user_role = (id, db) => {
|
||||||
|
return User.findByPk(id,
|
||||||
|
{
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.role,
|
||||||
|
required: false,
|
||||||
|
as: "role",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};User.get_user_credential = (id, db) => {
|
||||||
|
return User.findByPk(id,
|
||||||
|
{
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.credential,
|
||||||
|
required: false,
|
||||||
|
as: "credential",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};User.get_user_refer_log = (id, db) => {
|
||||||
|
return User.findByPk(id,
|
||||||
|
{
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.refer_log,
|
||||||
|
required: false,
|
||||||
|
as: "refer_logs",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};User.get_user_member_operation = (id, db) => {
|
||||||
|
return User.findByPk(id,
|
||||||
|
{
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.member_operation,
|
||||||
|
required: false,
|
||||||
|
as: "member_operations",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};User.get_user_admin_operation = (id, db) => {
|
||||||
|
return User.findByPk(id,
|
||||||
|
{
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.admin_operation,
|
||||||
|
required: false,
|
||||||
|
as: "admin_operations",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};User.get_user_token = (id, db) => {
|
||||||
|
return User.findByPk(id,
|
||||||
|
{
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.token,
|
||||||
|
required: false,
|
||||||
|
as: "tokens",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};User.get_user_image = (id, db) => {
|
||||||
|
return User.findByPk(id,
|
||||||
|
{
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: db.image,
|
||||||
|
required: false,
|
||||||
|
as: "images",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// ex
|
||||||
|
User.intersection = function (fields) {
|
||||||
|
if (fields) {
|
||||||
|
return intersection(
|
||||||
|
[
|
||||||
|
'id','role_id','profile_id','organization_id','first_name','last_name','phone','image','refer','stripe_uid','paypal_uid','expire_at','status','created_at','updated_at',
|
||||||
|
],
|
||||||
|
Object.keys(fields),
|
||||||
|
);
|
||||||
|
} else return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return User;
|
||||||
|
};
|
||||||
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,67 @@
|
|||||||
|
{
|
||||||
|
"name": "node_code_builder",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "lambda.js",
|
||||||
|
"scripts": {
|
||||||
|
"deploy": "claudia create --region us-east-2 --handler lambda.handler",
|
||||||
|
"update": "claudia update"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "Ryan Wong",
|
||||||
|
"private": true,
|
||||||
|
"license": "Private",
|
||||||
|
"dependencies": {
|
||||||
|
"apollo-server-express": "^2.11.0",
|
||||||
|
"aws-sdk": "^2.860.0",
|
||||||
|
"aws-serverless-express": "^3.3.7",
|
||||||
|
"axios": "^0.19.2",
|
||||||
|
"bcryptjs": "^2.4.3",
|
||||||
|
"body-parser": "^1.19.0",
|
||||||
|
"bootstrap-select": "^1.13.18",
|
||||||
|
"browserify": "^17.0.0",
|
||||||
|
"child_process": "^1.0.2",
|
||||||
|
"claudia": "^5.12.0",
|
||||||
|
"connect-flash": "^0.1.1",
|
||||||
|
"cookie-parser": "~1.4.4",
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"dotenv": "^8.2.0",
|
||||||
|
"eta": "^1.12",
|
||||||
|
"express": "^4.17.1",
|
||||||
|
"express-ip": "^1.0.4",
|
||||||
|
"express-session": "^1.17.1",
|
||||||
|
"fast-csv": "^4.3.6",
|
||||||
|
"firebase-admin": "^8.12.1",
|
||||||
|
"fs-extra": "^9.1.0",
|
||||||
|
"graphql-fields": "^2.0.3",
|
||||||
|
"helmet": "^3.19.0",
|
||||||
|
"html-pdf-node": "^1.0.7",
|
||||||
|
"image-size": "^1.0.0",
|
||||||
|
"jju": "^1.4.0",
|
||||||
|
"json-2-csv": "^3.11.0",
|
||||||
|
"json-to-csv": "^1.0.0",
|
||||||
|
"jsonwebtoken": "^8.5.1",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"mime-types": "^2.1.29",
|
||||||
|
"minify": "^7.0.1",
|
||||||
|
"moment": "^2.26.0",
|
||||||
|
"morgan": "~1.9.1",
|
||||||
|
"multer": "^1.4.2",
|
||||||
|
"multer-s3": "^2.9.0",
|
||||||
|
"mysql2": "^2.1.0",
|
||||||
|
"nanoid": "^3.1.20",
|
||||||
|
"node-input-validator": "^4.3.2",
|
||||||
|
"nodemailer": "^6.4.11",
|
||||||
|
"package-merge": "^0.1.2",
|
||||||
|
"qrcode": "^1.5.0",
|
||||||
|
"quagga": "^0.12.1",
|
||||||
|
"querystring": "^0.2.0",
|
||||||
|
"sanitize-html": "^2.4.0",
|
||||||
|
"semver-set": "^0.1.2",
|
||||||
|
"sequelize": "^5.21.3",
|
||||||
|
"stripe": "^8.138.0",
|
||||||
|
"twilio": "^3.41.1",
|
||||||
|
"uppload": "^3.2.1",
|
||||||
|
"winston": "^3.3.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,512 @@
|
|||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "TT Nooks Script";
|
||||||
|
src: url("/fonts/TTNooksScript-Bold.woff2") format("woff2"), url("/fonts/TTNooksScript-Bold.woff") format("woff");
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
src: url("/fonts/BradfordLL-Regular.woff2") format("woff2"), url("/fonts/BradfordLL-Regular.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
src: url("/fonts/BradfordLL-Italic.woff2") format("woff2"), url("/fonts/BradfordLL-Italic.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
src: url("/fonts/Necto-Mono.woff2") format("woff2"), url("/fonts/Necto-Mono.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Debrovnik Hill Italic";
|
||||||
|
src: url("/fonts/Debrovnik Hill Italic.ttf") format("truetype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Debrovnik Hill Reguler";
|
||||||
|
src: url("/fonts/Debrovnik Hill Reguler.ttf") format("truetype");
|
||||||
|
}
|
||||||
|
html {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: visible;
|
||||||
|
flex-grow: 1;
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
}
|
||||||
|
.logo-svg {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
#main-letter {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
width: 100%;
|
||||||
|
/* max-width: 618px; */
|
||||||
|
margin: auto;
|
||||||
|
background-color: white;
|
||||||
|
height: 100vh;
|
||||||
|
/* min-height: 100%; */
|
||||||
|
}
|
||||||
|
#main-letter.print {
|
||||||
|
max-width: unset;
|
||||||
|
}
|
||||||
|
#main-letter .left,
|
||||||
|
#main-letter .right {
|
||||||
|
width: max-content;
|
||||||
|
padding: 20px 8px;
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-style: italic;
|
||||||
|
text-transform: capitalize;
|
||||||
|
font-size: 20px;
|
||||||
|
min-height: max-content;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#main-letter .left {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
writing-mode: vertical-lr;
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
#main-letter .right {
|
||||||
|
writing-mode: vertical-rl;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
#main-letter .center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
border: 1px solid black;
|
||||||
|
border-top: none;
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
#main-letter .center .top {
|
||||||
|
padding: 20px 0 24px;
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
}
|
||||||
|
#main-letter .center .top .header-logo {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: max-content;
|
||||||
|
padding: 1px 24px;
|
||||||
|
margin: 0 auto;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
#main-letter .center .top .header-logo::after {
|
||||||
|
content: "";
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 1.5px;
|
||||||
|
border-radius: 1px;
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
#main-letter .center .header-logo .cr-logo {
|
||||||
|
font-family: "TT Nooks Script";
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 40px;
|
||||||
|
}
|
||||||
|
#main-letter .center .header-logo .customer-name {
|
||||||
|
text-align: center;
|
||||||
|
font-family: "Debrovnik Hill Italic";
|
||||||
|
text-transform: capitalize;
|
||||||
|
font-weight: 700;
|
||||||
|
color: black;
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main-letter .center .middle {
|
||||||
|
padding: 24px 56px;
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
}
|
||||||
|
#main-letter .center .middle .header {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-size: 28px;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
#main-letter .center .middle .body .customer-name {
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
#main-letter .center .middle .body p {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
line-height: 140%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main-letter .center .footer {
|
||||||
|
margin-top: 24px;
|
||||||
|
}
|
||||||
|
#main-letter .center .footer h5 {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
#profile-letter {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
width: 100%;
|
||||||
|
/* min-height: 100%; */
|
||||||
|
/* max-width: 618px; */
|
||||||
|
margin: auto;
|
||||||
|
height: 100vh;
|
||||||
|
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
#profile-letter.print {
|
||||||
|
max-width: unset;
|
||||||
|
}
|
||||||
|
#profile-letter .left,
|
||||||
|
#profile-letter .right {
|
||||||
|
width: max-content;
|
||||||
|
padding: 20px 8px;
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-style: italic;
|
||||||
|
text-transform: capitalize;
|
||||||
|
font-size: 20px;
|
||||||
|
height: 100%;
|
||||||
|
min-height: max-content;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#profile-letter .left {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
writing-mode: vertical-lr;
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
#profile-letter .right {
|
||||||
|
writing-mode: vertical-rl;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
#profile-letter .center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
border: 1px solid black;
|
||||||
|
border-top: none;
|
||||||
|
border-bottom: none;
|
||||||
|
min-height: 100%;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
#profile-letter .center .header {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 32px;
|
||||||
|
text-transform: capitalize;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
#profile-letter .center .body {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#profile-letter .progress-container {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 100%;
|
||||||
|
padding: 14px 20px 20px 20px;
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
}
|
||||||
|
#profile-letter .progress-container:last-of-type {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#profile-letter .progress-container .profile-title h3 {
|
||||||
|
color: #000000;
|
||||||
|
text-align: center;
|
||||||
|
font: italic 30px "Bradford LL";
|
||||||
|
line-height: 40px;
|
||||||
|
margin: 0;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
#profile-letter .progress-container .profile-body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
#profile-letter .profile-container {
|
||||||
|
width: 45%;
|
||||||
|
margin: 0 0 18px 0;
|
||||||
|
}
|
||||||
|
#profile-letter .profile-container .title {
|
||||||
|
font: 16px "Necto Mono";
|
||||||
|
color: #231f20;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
#profile-letter .profile-container .progress {
|
||||||
|
width: 100%;
|
||||||
|
height: 6px;
|
||||||
|
border: 1px solid black;
|
||||||
|
border-radius: 1px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
#profile-letter .profile-container .progress .bar {
|
||||||
|
height: 100%;
|
||||||
|
background-color: black;
|
||||||
|
z-index: 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
#formula-letter {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
/* max-width: 618px; */
|
||||||
|
margin: auto;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
#formula-letter.print {
|
||||||
|
max-width: unset;
|
||||||
|
}
|
||||||
|
#formula-letter .left,
|
||||||
|
#formula-letter .right {
|
||||||
|
width: max-content;
|
||||||
|
padding: 20px 8px;
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-style: italic;
|
||||||
|
text-transform: capitalize;
|
||||||
|
font-size: 20px;
|
||||||
|
height: 100%;
|
||||||
|
min-height: max-content;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#formula-letter .left {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
writing-mode: vertical-lr;
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
#formula-letter .right {
|
||||||
|
writing-mode: vertical-rl;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
#formula-letter .center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
border: 1px solid black;
|
||||||
|
border-top: none;
|
||||||
|
border-bottom: none;
|
||||||
|
min-height: 100%;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
#formula-letter .center .header {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 32px;
|
||||||
|
text-transform: capitalize;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
#formula-letter .center .body {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step div {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step .title {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-size: 26px;
|
||||||
|
font-style: italic;
|
||||||
|
text-align: left;
|
||||||
|
padding-left: 8px;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step._two .title {
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step._two .content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
grid-auto-rows: 1fr;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step._two .content .active {
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step._two .content .active:nth-child(odd) {
|
||||||
|
border-right: 1px solid black;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step .content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
flex-grow: 1;
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
}
|
||||||
|
|
||||||
|
#formula-letter .center .step .content .qrcode {
|
||||||
|
width: max-content;
|
||||||
|
margin-right: 8px;
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step .content .explanation {
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding-right: 4px;
|
||||||
|
}
|
||||||
|
#formula-letter .step._two .name-qrcode {
|
||||||
|
margin-top: 4px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
#formula-letter .step._two .name-qrcode .active-name {
|
||||||
|
padding-left: 8px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
#formula-letter .step._two .description {
|
||||||
|
padding: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-size: 13px;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
#formula-letter .footer-note {
|
||||||
|
padding: 10px;
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: italic;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#instructions-letter {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
width: 100%;
|
||||||
|
/* max-width: 618px; */
|
||||||
|
margin: auto;
|
||||||
|
background-color: white;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
#instructions-letter.print {
|
||||||
|
max-width: unset;
|
||||||
|
}
|
||||||
|
#instructions-letter .left,
|
||||||
|
#instructions-letter .right {
|
||||||
|
width: max-content;
|
||||||
|
padding: 20px 8px;
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-style: italic;
|
||||||
|
text-transform: capitalize;
|
||||||
|
font-size: 20px;
|
||||||
|
min-height: max-content;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#instructions-letter .left {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
writing-mode: vertical-lr;
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
#instructions-letter .right {
|
||||||
|
writing-mode: vertical-rl;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
#instructions-letter .center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
border: 1px solid black;
|
||||||
|
border-top: none;
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
#instructions-letter .center .header {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 36px;
|
||||||
|
text-transform: capitalize;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
#instructions-letter .section {
|
||||||
|
padding: 8px 10px;
|
||||||
|
}
|
||||||
|
#instructions-letter .section .sub-header {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-weight: 500;
|
||||||
|
margin-top: 0;
|
||||||
|
font-size: 28px;
|
||||||
|
font-style: italic;
|
||||||
|
text-transform: capitalize;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
#instructions-letter .items .list {
|
||||||
|
list-style: none;
|
||||||
|
margin-top: 0;
|
||||||
|
padding-left: 16px;
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
#instructions-letter .items .list li {
|
||||||
|
padding-bottom: 6px;
|
||||||
|
}
|
||||||
|
#instructions-letter .items .list li ul {
|
||||||
|
margin-top: 6px;
|
||||||
|
padding-left: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#instructions-letter .mixing-steps .list {
|
||||||
|
margin-top: 0;
|
||||||
|
padding-left: 56px;
|
||||||
|
padding-right: 16px;
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
#instructions-letter .mixing-steps .list li {
|
||||||
|
padding-bottom: 6px;
|
||||||
|
}
|
||||||
|
#instructions-letter .notes .list {
|
||||||
|
list-style: disc;
|
||||||
|
margin-top: 0;
|
||||||
|
padding-left: 48px;
|
||||||
|
padding-right: 16px;
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,197 @@
|
|||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "TT Nooks Script";
|
||||||
|
src: url("/fonts/TTNooksScript-Bold.woff2") format("woff2"), url("/fonts/TTNooksScript-Bold.woff") format("woff");
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
src: url("/fonts/BradfordLL-Regular.woff2") format("woff2"), url("/fonts/BradfordLL-Regular.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
src: url("/fonts/BradfordLL-Italic.woff2") format("woff2"), url("/fonts/BradfordLL-Italic.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
src: url("/fonts/Necto-Mono.woff2") format("woff2"), url("/fonts/Necto-Mono.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Debrovnik Hill Italic";
|
||||||
|
src: url("/fonts/Debrovnik Hill Italic.ttf") format("truetype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Debrovnik Hill Reguler";
|
||||||
|
src: url("/fonts/Debrovnik Hill Reguler.ttf") format("truetype");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "rotation-roman";
|
||||||
|
src: url("/fonts/RotationLTStd-Roman.otf") format("opentype");
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
}
|
||||||
|
.logo-svg {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
#formula-letter {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
/* max-width: 618px; */
|
||||||
|
margin: auto;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
#formula-letter.print {
|
||||||
|
max-width: unset;
|
||||||
|
}
|
||||||
|
#formula-letter .left,
|
||||||
|
#formula-letter .right {
|
||||||
|
width: max-content;
|
||||||
|
padding: 20px 8px;
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-style: italic;
|
||||||
|
text-transform: capitalize;
|
||||||
|
font-size: 20px;
|
||||||
|
height: 100%;
|
||||||
|
min-height: max-content;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#formula-letter .left {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
margin-left: 6px;
|
||||||
|
writing-mode: vertical-lr;
|
||||||
|
}
|
||||||
|
#formula-letter .right {
|
||||||
|
margin-right: 6px;
|
||||||
|
writing-mode: vertical-rl;
|
||||||
|
}
|
||||||
|
#formula-letter .center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
border: 1px solid black;
|
||||||
|
border-top: none;
|
||||||
|
border-bottom: none;
|
||||||
|
min-height: 100%;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
#formula-letter .center .header {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 32px;
|
||||||
|
text-transform: capitalize;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
#formula-letter .center .body {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step div {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step .title {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-size: 26px;
|
||||||
|
font-style: italic;
|
||||||
|
text-align: left;
|
||||||
|
padding-left: 8px;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step._two .title {
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step._two .content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
grid-auto-rows: 1fr;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step._two .content .active {
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step._two .content .active:nth-child(odd) {
|
||||||
|
border-right: 1px solid black;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step .content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
flex-grow: 1;
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
}
|
||||||
|
|
||||||
|
#formula-letter .center .step .content .qrcode {
|
||||||
|
width: max-content;
|
||||||
|
margin-right: 8px;
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
#formula-letter .center .step .content .explanation {
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding-right: 4px;
|
||||||
|
}
|
||||||
|
#formula-letter .step._two .name-qrcode {
|
||||||
|
margin-top: 4px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
#formula-letter .step._two .name-qrcode .active-name {
|
||||||
|
padding-left: 8px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
#formula-letter .step._two .description {
|
||||||
|
padding: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-size: 13px;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
#formula-letter .footer-note {
|
||||||
|
padding: 10px;
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: italic;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "TT Nooks Script";
|
||||||
|
src: url("/fonts/TTNooksScript-Bold.woff2") format("woff2"), url("/fonts/TTNooksScript-Bold.woff") format("woff");
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
src: url("/fonts/BradfordLL-Regular.woff2") format("woff2"), url("/fonts/BradfordLL-Regular.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
src: url("/fonts/BradfordLL-Italic.woff2") format("woff2"), url("/fonts/BradfordLL-Italic.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
src: url("/fonts/Necto-Mono.woff2") format("woff2"), url("/fonts/Necto-Mono.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Debrovnik Hill Italic";
|
||||||
|
src: url("/fonts/Debrovnik Hill Italic.ttf") format("truetype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Debrovnik Hill Reguler";
|
||||||
|
src: url("/fonts/Debrovnik Hill Reguler.ttf") format("truetype");
|
||||||
|
}
|
||||||
|
html {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: visible;
|
||||||
|
flex-grow: 1;
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
}
|
||||||
|
.logo-svg {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#instructions-letter {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
width: 100%;
|
||||||
|
/* max-width: 618px; */
|
||||||
|
margin: auto;
|
||||||
|
background-color: white;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
#instructions-letter.print {
|
||||||
|
max-width: unset;
|
||||||
|
}
|
||||||
|
#instructions-letter .left,
|
||||||
|
#instructions-letter .right {
|
||||||
|
width: max-content;
|
||||||
|
padding: 20px 8px;
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-style: italic;
|
||||||
|
text-transform: capitalize;
|
||||||
|
font-size: 20px;
|
||||||
|
min-height: max-content;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#instructions-letter .left {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
writing-mode: vertical-lr;
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
#instructions-letter .right {
|
||||||
|
margin-right: 6px;
|
||||||
|
writing-mode: vertical-rl;
|
||||||
|
}
|
||||||
|
#instructions-letter .center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
border: 1px solid black;
|
||||||
|
border-top: none;
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
#instructions-letter .center .header {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 36px;
|
||||||
|
text-transform: capitalize;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
#instructions-letter .section {
|
||||||
|
padding: 8px 10px;
|
||||||
|
}
|
||||||
|
#instructions-letter .section .sub-header {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-weight: 500;
|
||||||
|
margin-top: 0;
|
||||||
|
font-size: 28px;
|
||||||
|
font-style: italic;
|
||||||
|
text-transform: capitalize;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
#instructions-letter .items .list {
|
||||||
|
list-style: none;
|
||||||
|
margin-top: 0;
|
||||||
|
padding-left: 16px;
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
#instructions-letter .items .list li {
|
||||||
|
padding-bottom: 6px;
|
||||||
|
}
|
||||||
|
#instructions-letter .items .list li ul {
|
||||||
|
margin-top: 6px;
|
||||||
|
padding-left: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#instructions-letter .mixing-steps .list {
|
||||||
|
margin-top: 0;
|
||||||
|
padding-left: 56px;
|
||||||
|
padding-right: 16px;
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
#instructions-letter .mixing-steps .list li {
|
||||||
|
padding-bottom: 6px;
|
||||||
|
}
|
||||||
|
#instructions-letter .notes .list {
|
||||||
|
list-style: disc;
|
||||||
|
margin-top: 0;
|
||||||
|
padding-left: 48px;
|
||||||
|
padding-right: 16px;
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "TT Nooks Script";
|
||||||
|
src: url("/fonts/TTNooksScript-Bold.woff2") format("woff2"), url("/fonts/TTNooksScript-Bold.woff") format("woff");
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
src: url("/fonts/BradfordLL-Regular.woff2") format("woff2"), url("/fonts/BradfordLL-Regular.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
src: url("/fonts/BradfordLL-Italic.woff2") format("woff2"), url("/fonts/BradfordLL-Italic.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
src: url("/fonts/Necto-Mono.woff2") format("woff2"), url("/fonts/Necto-Mono.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Debrovnik Hill Italic";
|
||||||
|
src: url("/fonts/Debrovnik Hill Italic.ttf") format("truetype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Debrovnik Hill Reguler";
|
||||||
|
src: url("/fonts/Debrovnik Hill Reguler.ttf") format("truetype");
|
||||||
|
}
|
||||||
|
html {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: visible;
|
||||||
|
flex-grow: 1;
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
}
|
||||||
|
#main-letter {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
width: 100%;
|
||||||
|
margin: auto;
|
||||||
|
background-color: white;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
#main-letter.print {
|
||||||
|
max-width: unset;
|
||||||
|
}
|
||||||
|
#main-letter .left,
|
||||||
|
#main-letter .right {
|
||||||
|
width: max-content;
|
||||||
|
padding: 20px 8px;
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-style: italic;
|
||||||
|
text-transform: capitalize;
|
||||||
|
font-size: 20px;
|
||||||
|
min-height: max-content;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#main-letter .left {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
writing-mode: vertical-lr;
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
#main-letter .right {
|
||||||
|
writing-mode: vertical-rl;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
#main-letter .center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
border: 1px solid black;
|
||||||
|
border-top: none;
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
#main-letter .center .top {
|
||||||
|
padding: 20px 0 24px;
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
}
|
||||||
|
#main-letter .center .top .header-logo {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: max-content;
|
||||||
|
padding: 1px 24px;
|
||||||
|
margin: 0 auto;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
#main-letter .center .top .header-logo::after {
|
||||||
|
content: "";
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 1.5px;
|
||||||
|
border-radius: 1px;
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
#main-letter .center .header-logo .cr-logo {
|
||||||
|
font-family: "TT Nooks Script";
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 40px;
|
||||||
|
}
|
||||||
|
#main-letter .center .header-logo .customer-name {
|
||||||
|
text-align: center;
|
||||||
|
font-family: "Debrovnik Hill Italic";
|
||||||
|
text-transform: capitalize;
|
||||||
|
font-weight: 700;
|
||||||
|
color: black;
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main-letter .center .middle {
|
||||||
|
padding: 24px 56px;
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
}
|
||||||
|
#main-letter .center .middle .header {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-size: 28px;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
#main-letter .center .middle .body .customer-name {
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
#main-letter .center .middle .body p {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
line-height: 140%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.logo-svg {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
#main-letter .center .footer {
|
||||||
|
margin-top: 24px;
|
||||||
|
}
|
||||||
|
#main-letter .center .footer h5 {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
@import "https://unpkg.com/uppload/dist/uppload.css";
|
||||||
|
@import "https://unpkg.com/uppload/dist/themes/light.css";
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "TT Nooks Script";
|
||||||
|
src: url("/fonts/TTNooksScript-Bold.woff2") format("woff2"), url("/fonts/TTNooksScript-Bold.woff") format("woff");
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
src: url("/fonts/BradfordLL-Regular.woff2") format("woff2"), url("/fonts/BradfordLL-Regular.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
src: url("/fonts/BradfordLL-Italic.woff2") format("woff2"), url("/fonts/BradfordLL-Italic.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
src: url("/fonts/Necto-Mono.woff2") format("woff2"), url("/fonts/Necto-Mono.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Debrovnik Hill Italic";
|
||||||
|
src: url("/fonts/Debrovnik Hill Italic.ttf") format("truetype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Debrovnik Hill Reguler";
|
||||||
|
src: url("/fonts/Debrovnik Hill Reguler.ttf") format("truetype");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "rotation-roman";
|
||||||
|
src: url("/fonts/RotationLTStd-Roman.otf") format("opentype");
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
}
|
||||||
|
.logo-svg {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
#profile-letter {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
/* max-width: 618px; */
|
||||||
|
margin: auto;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
#profile-letter.print {
|
||||||
|
max-width: unset;
|
||||||
|
}
|
||||||
|
#profile-letter .left,
|
||||||
|
#profile-letter .right {
|
||||||
|
width: max-content;
|
||||||
|
padding: 20px 8px;
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-style: italic;
|
||||||
|
text-transform: capitalize;
|
||||||
|
font-size: 20px;
|
||||||
|
height: 100%;
|
||||||
|
min-height: max-content;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#profile-letter .left {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
margin-left: 6px;
|
||||||
|
writing-mode: vertical-lr;
|
||||||
|
}
|
||||||
|
#profile-letter .right {
|
||||||
|
margin-right: 6px;
|
||||||
|
writing-mode: vertical-rl;
|
||||||
|
}
|
||||||
|
#profile-letter .center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
border: 1px solid black;
|
||||||
|
border-top: none;
|
||||||
|
border-bottom: none;
|
||||||
|
min-height: 100%;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
#profile-letter .center .header {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 32px;
|
||||||
|
text-transform: capitalize;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
#profile-letter .center .body {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#profile-letter .progress-container {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 100%;
|
||||||
|
padding: 14px 20px 20px 20px;
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
}
|
||||||
|
#profile-letter .progress-container:last-of-type {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#profile-letter .progress-container .profile-title h3 {
|
||||||
|
color: #000000;
|
||||||
|
text-align: center;
|
||||||
|
font: italic 30px "Bradford LL";
|
||||||
|
line-height: 40px;
|
||||||
|
margin: 0;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
#profile-letter .progress-container .profile-body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
#profile-letter .profile-container {
|
||||||
|
width: 45%;
|
||||||
|
margin: 0 0 18px 0;
|
||||||
|
}
|
||||||
|
#profile-letter .profile-container .title {
|
||||||
|
font: 16px "Necto Mono";
|
||||||
|
color: #231f20;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
#profile-letter .profile-container .progress {
|
||||||
|
width: 100%;
|
||||||
|
height: 6px;
|
||||||
|
border: 1px solid black;
|
||||||
|
border-radius: 1px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
#profile-letter .profile-container .progress .bar {
|
||||||
|
height: 100%;
|
||||||
|
background-color: black;
|
||||||
|
z-index: 9;
|
||||||
|
}
|
||||||
@@ -0,0 +1,709 @@
|
|||||||
|
.select2-container {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.select2-container .select2-selection--single {
|
||||||
|
box-sizing: border-box;
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
height: 28px;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
}
|
||||||
|
.select2-container .select2-selection--single .select2-selection__rendered {
|
||||||
|
display: block;
|
||||||
|
padding-left: 8px;
|
||||||
|
padding-right: 20px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.select2-container .select2-selection--single .select2-selection__clear {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
.select2-container[dir='rtl']
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__rendered {
|
||||||
|
padding-right: 8px;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
.select2-container .select2-selection--multiple {
|
||||||
|
box-sizing: border-box;
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
min-height: 32px;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
}
|
||||||
|
.select2-container .select2-selection--multiple .select2-selection__rendered {
|
||||||
|
display: inline;
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.select2-container .select2-selection--multiple .select2-selection__clear {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
.select2-container .select2-search--inline .select2-search__field {
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: none;
|
||||||
|
font-size: 100%;
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-left: 5px;
|
||||||
|
padding: 0;
|
||||||
|
max-width: 100%;
|
||||||
|
resize: none;
|
||||||
|
height: 18px;
|
||||||
|
vertical-align: bottom;
|
||||||
|
font-family: sans-serif;
|
||||||
|
overflow: hidden;
|
||||||
|
word-break: keep-all;
|
||||||
|
}
|
||||||
|
.select2-container
|
||||||
|
.select2-search--inline
|
||||||
|
.select2-search__field::-webkit-search-cancel-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
.select2-dropdown {
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
left: -100000px;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 1051;
|
||||||
|
}
|
||||||
|
.select2-results {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.select2-results__options {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.select2-results__option {
|
||||||
|
padding: 6px;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
}
|
||||||
|
.select2-results__option--selectable {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.select2-container--open .select2-dropdown {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.select2-container--open .select2-dropdown--above {
|
||||||
|
border-bottom: none;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
.select2-container--open .select2-dropdown--below {
|
||||||
|
border-top: none;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
}
|
||||||
|
.select2-search--dropdown {
|
||||||
|
display: block;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
.select2-search--dropdown .select2-search__field {
|
||||||
|
padding: 4px;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
.select2-search--dropdown.select2-search--hide {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.select2-close-mask {
|
||||||
|
border: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: block;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
min-height: 100%;
|
||||||
|
min-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
width: auto;
|
||||||
|
opacity: 0;
|
||||||
|
z-index: 99;
|
||||||
|
background-color: #fff;
|
||||||
|
filter: alpha(opacity=0);
|
||||||
|
}
|
||||||
|
.select2-hidden-accessible {
|
||||||
|
border: 0 !important;
|
||||||
|
clip: rect(0 0 0 0) !important;
|
||||||
|
-webkit-clip-path: inset(50%) !important;
|
||||||
|
clip-path: inset(50%) !important;
|
||||||
|
height: 1px !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
position: absolute !important;
|
||||||
|
width: 1px !important;
|
||||||
|
white-space: nowrap !important;
|
||||||
|
}
|
||||||
|
.select2-container--default .select2-selection--single {
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__rendered {
|
||||||
|
color: #444;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__clear {
|
||||||
|
cursor: pointer;
|
||||||
|
float: right;
|
||||||
|
font-weight: bold;
|
||||||
|
height: 26px;
|
||||||
|
margin-right: 20px;
|
||||||
|
padding-right: 0px;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__placeholder {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__arrow {
|
||||||
|
height: 26px;
|
||||||
|
position: absolute;
|
||||||
|
top: 1px;
|
||||||
|
right: 1px;
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__arrow
|
||||||
|
b {
|
||||||
|
border-color: #888 transparent transparent transparent;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 5px 4px 0 4px;
|
||||||
|
height: 0;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -4px;
|
||||||
|
margin-top: -2px;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
.select2-container--default[dir='rtl']
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__clear {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.select2-container--default[dir='rtl']
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__arrow {
|
||||||
|
left: 1px;
|
||||||
|
right: auto;
|
||||||
|
}
|
||||||
|
.select2-container--default.select2-container--disabled
|
||||||
|
.select2-selection--single {
|
||||||
|
background-color: #eee;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.select2-container--default.select2-container--disabled
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__clear {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.select2-container--default.select2-container--open
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__arrow
|
||||||
|
b {
|
||||||
|
border-color: transparent transparent #888 transparent;
|
||||||
|
border-width: 0 4px 5px 4px;
|
||||||
|
}
|
||||||
|
.select2-container--default .select2-selection--multiple {
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: text;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-selection--multiple.select2-selection--clearable {
|
||||||
|
padding-right: 25px;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__clear {
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: bold;
|
||||||
|
height: 20px;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-top: 5px;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
padding: 1px;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__choice {
|
||||||
|
background-color: #e4e4e4;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-top: 5px;
|
||||||
|
padding: 0;
|
||||||
|
padding-left: 20px;
|
||||||
|
position: relative;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
vertical-align: bottom;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__choice__display {
|
||||||
|
cursor: default;
|
||||||
|
padding-left: 2px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__choice__remove {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
border-right: 1px solid #aaa;
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
color: #999;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 0 4px;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__choice__remove:hover,
|
||||||
|
.select2-container--default
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__choice__remove:focus {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
color: #333;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.select2-container--default[dir='rtl']
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__choice {
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
.select2-container--default[dir='rtl']
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__choice__display {
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 2px;
|
||||||
|
}
|
||||||
|
.select2-container--default[dir='rtl']
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__choice__remove {
|
||||||
|
border-left: 1px solid #aaa;
|
||||||
|
border-right: none;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
}
|
||||||
|
.select2-container--default[dir='rtl']
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__clear {
|
||||||
|
float: left;
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
.select2-container--default.select2-container--focus
|
||||||
|
.select2-selection--multiple {
|
||||||
|
border: solid black 1px;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
.select2-container--default.select2-container--disabled
|
||||||
|
.select2-selection--multiple {
|
||||||
|
background-color: #eee;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.select2-container--default.select2-container--disabled
|
||||||
|
.select2-selection__choice__remove {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.select2-container--default.select2-container--open.select2-container--above
|
||||||
|
.select2-selection--single,
|
||||||
|
.select2-container--default.select2-container--open.select2-container--above
|
||||||
|
.select2-selection--multiple {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
}
|
||||||
|
.select2-container--default.select2-container--open.select2-container--below
|
||||||
|
.select2-selection--single,
|
||||||
|
.select2-container--default.select2-container--open.select2-container--below
|
||||||
|
.select2-selection--multiple {
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
.select2-container--default .select2-search--dropdown .select2-search__field {
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
}
|
||||||
|
.select2-container--default .select2-search--inline .select2-search__field {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
outline: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
-webkit-appearance: textfield;
|
||||||
|
}
|
||||||
|
.select2-container--default .select2-results > .select2-results__options {
|
||||||
|
max-height: 200px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.select2-container--default .select2-results__option .select2-results__option {
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__group {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option {
|
||||||
|
margin-left: -1em;
|
||||||
|
padding-left: 2em;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option {
|
||||||
|
margin-left: -2em;
|
||||||
|
padding-left: 3em;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option {
|
||||||
|
margin-left: -3em;
|
||||||
|
padding-left: 4em;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option {
|
||||||
|
margin-left: -4em;
|
||||||
|
padding-left: 5em;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option
|
||||||
|
.select2-results__option {
|
||||||
|
margin-left: -5em;
|
||||||
|
padding-left: 6em;
|
||||||
|
}
|
||||||
|
.select2-container--default .select2-results__option--group {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.select2-container--default .select2-results__option--disabled {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.select2-container--default .select2-results__option--selected {
|
||||||
|
background-color: #ddd;
|
||||||
|
}
|
||||||
|
.select2-container--default
|
||||||
|
.select2-results__option--highlighted.select2-results__option--selectable {
|
||||||
|
background-color: #5897fb;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.select2-container--default .select2-results__group {
|
||||||
|
cursor: default;
|
||||||
|
display: block;
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
.select2-container--classic .select2-selection--single {
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
border-radius: 4px;
|
||||||
|
outline: 0;
|
||||||
|
background-image: -webkit-linear-gradient(top, #fff 50%, #eee 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #fff 50%, #eee 100%);
|
||||||
|
background-image: linear-gradient(to bottom, #fff 50%, #eee 100%);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0);
|
||||||
|
}
|
||||||
|
.select2-container--classic .select2-selection--single:focus {
|
||||||
|
border: 1px solid #5897fb;
|
||||||
|
}
|
||||||
|
.select2-container--classic
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__rendered {
|
||||||
|
color: #444;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
.select2-container--classic
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__clear {
|
||||||
|
cursor: pointer;
|
||||||
|
float: right;
|
||||||
|
font-weight: bold;
|
||||||
|
height: 26px;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
.select2-container--classic
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__placeholder {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.select2-container--classic
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__arrow {
|
||||||
|
background-color: #ddd;
|
||||||
|
border: none;
|
||||||
|
border-left: 1px solid #aaa;
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
height: 26px;
|
||||||
|
position: absolute;
|
||||||
|
top: 1px;
|
||||||
|
right: 1px;
|
||||||
|
width: 20px;
|
||||||
|
background-image: -webkit-linear-gradient(top, #eee 50%, #ccc 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #eee 50%, #ccc 100%);
|
||||||
|
background-image: linear-gradient(to bottom, #eee 50%, #ccc 100%);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0);
|
||||||
|
}
|
||||||
|
.select2-container--classic
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__arrow
|
||||||
|
b {
|
||||||
|
border-color: #888 transparent transparent transparent;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 5px 4px 0 4px;
|
||||||
|
height: 0;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -4px;
|
||||||
|
margin-top: -2px;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
.select2-container--classic[dir='rtl']
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__clear {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.select2-container--classic[dir='rtl']
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__arrow {
|
||||||
|
border: none;
|
||||||
|
border-right: 1px solid #aaa;
|
||||||
|
border-radius: 0;
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
left: 1px;
|
||||||
|
right: auto;
|
||||||
|
}
|
||||||
|
.select2-container--classic.select2-container--open .select2-selection--single {
|
||||||
|
border: 1px solid #5897fb;
|
||||||
|
}
|
||||||
|
.select2-container--classic.select2-container--open
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__arrow {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.select2-container--classic.select2-container--open
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__arrow
|
||||||
|
b {
|
||||||
|
border-color: transparent transparent #888 transparent;
|
||||||
|
border-width: 0 4px 5px 4px;
|
||||||
|
}
|
||||||
|
.select2-container--classic.select2-container--open.select2-container--above
|
||||||
|
.select2-selection--single {
|
||||||
|
border-top: none;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
background-image: -webkit-linear-gradient(top, #fff 0%, #eee 50%);
|
||||||
|
background-image: -o-linear-gradient(top, #fff 0%, #eee 50%);
|
||||||
|
background-image: linear-gradient(to bottom, #fff 0%, #eee 50%);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0);
|
||||||
|
}
|
||||||
|
.select2-container--classic.select2-container--open.select2-container--below
|
||||||
|
.select2-selection--single {
|
||||||
|
border-bottom: none;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
background-image: -webkit-linear-gradient(top, #eee 50%, #fff 100%);
|
||||||
|
background-image: -o-linear-gradient(top, #eee 50%, #fff 100%);
|
||||||
|
background-image: linear-gradient(to bottom, #eee 50%, #fff 100%);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0);
|
||||||
|
}
|
||||||
|
.select2-container--classic .select2-selection--multiple {
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: text;
|
||||||
|
outline: 0;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
.select2-container--classic .select2-selection--multiple:focus {
|
||||||
|
border: 1px solid #5897fb;
|
||||||
|
}
|
||||||
|
.select2-container--classic
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__clear {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.select2-container--classic
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__choice {
|
||||||
|
background-color: #e4e4e4;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-top: 5px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.select2-container--classic
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__choice__display {
|
||||||
|
cursor: default;
|
||||||
|
padding-left: 2px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
.select2-container--classic
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__choice__remove {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
color: #888;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
.select2-container--classic
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__choice__remove:hover {
|
||||||
|
color: #555;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.select2-container--classic[dir='rtl']
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__choice {
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
.select2-container--classic[dir='rtl']
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__choice__display {
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 2px;
|
||||||
|
}
|
||||||
|
.select2-container--classic[dir='rtl']
|
||||||
|
.select2-selection--multiple
|
||||||
|
.select2-selection__choice__remove {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
}
|
||||||
|
.select2-container--classic.select2-container--open
|
||||||
|
.select2-selection--multiple {
|
||||||
|
border: 1px solid #5897fb;
|
||||||
|
}
|
||||||
|
.select2-container--classic.select2-container--open.select2-container--above
|
||||||
|
.select2-selection--multiple {
|
||||||
|
border-top: none;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
}
|
||||||
|
.select2-container--classic.select2-container--open.select2-container--below
|
||||||
|
.select2-selection--multiple {
|
||||||
|
border-bottom: none;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
.select2-container--classic .select2-search--dropdown .select2-search__field {
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
.select2-container--classic .select2-search--inline .select2-search__field {
|
||||||
|
outline: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.select2-container--classic .select2-dropdown {
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
}
|
||||||
|
.select2-container--classic .select2-dropdown--above {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
.select2-container--classic .select2-dropdown--below {
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
.select2-container--classic .select2-results > .select2-results__options {
|
||||||
|
max-height: 200px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.select2-container--classic .select2-results__option--group {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.select2-container--classic .select2-results__option--disabled {
|
||||||
|
color: grey;
|
||||||
|
}
|
||||||
|
.select2-container--classic
|
||||||
|
.select2-results__option--highlighted.select2-results__option--selectable {
|
||||||
|
background-color: #3875d7;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.select2-container--classic .select2-results__group {
|
||||||
|
cursor: default;
|
||||||
|
display: block;
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
.select2-container--classic.select2-container--open .select2-dropdown {
|
||||||
|
border-color: #5897fb;
|
||||||
|
}
|
||||||
@@ -0,0 +1,880 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
@font-face {
|
||||||
|
font-family: "TT Nooks Script";
|
||||||
|
src: url("/fonts/TTNooksScript-Bold.woff2") format("woff2"), url("/fonts/TTNooksScript-Bold.woff") format("woff");
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
src: url("/fonts/BradfordLL-Regular.woff2") format("woff2"), url("/fonts/BradfordLL-Regular.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Bradford LL";
|
||||||
|
src: url("/fonts/BradfordLL-Italic.woff2") format("woff2"), url("/fonts/BradfordLL-Italic.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Necto Mono";
|
||||||
|
src: url("/fonts/Necto-Mono.woff2") format("woff2"), url("/fonts/Necto-Mono.woff") format("woff");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Debrovnik Hill Italic";
|
||||||
|
src: url("/fonts/Debrovnik Hill Italic.ttf") format("truetype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Debrovnik Hill Reguler";
|
||||||
|
src: url("/fonts/Debrovnik Hill Reguler.ttf") format("truetype");
|
||||||
|
}
|
||||||
|
#mkd-login-container,
|
||||||
|
.mkd-form-signup-container {
|
||||||
|
width: 412px;
|
||||||
|
margin: 10vh auto;
|
||||||
|
background-color: #f3f3f3;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
|
||||||
|
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||||
|
}
|
||||||
|
#mkd-login-container form,
|
||||||
|
.mkd-form-signup-container form {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 410px;
|
||||||
|
padding: 15px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
#mkd-login-container .form-control,
|
||||||
|
.mkd-form-signup-container .form-control {
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: auto;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
#mkd-login-container .form-control:focus,
|
||||||
|
.mkd-form-signup-container .form-control:focus {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
#mkd-login-container .mkd-login-form-container input[type="email"],
|
||||||
|
.mkd-form-signup-container .mkd-login-form-container input[type="email"] {
|
||||||
|
margin-bottom: -1px;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
#mkd-login-container .mkd-login-form-container input[type="password"],
|
||||||
|
.mkd-form-signup-container .mkd-login-form-container input[type="password"] {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
}
|
||||||
|
#mkd-login-container .social-login,
|
||||||
|
.mkd-form-signup-container .social-login {
|
||||||
|
width: 390px;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
#mkd-login-container .social-btn,
|
||||||
|
.mkd-form-signup-container .social-btn {
|
||||||
|
font-weight: 100;
|
||||||
|
color: white;
|
||||||
|
width: 49%;
|
||||||
|
display: inline;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin: 0 2px;
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
#mkd-login-container a,
|
||||||
|
.mkd-form-signup-container a {
|
||||||
|
display: block;
|
||||||
|
padding-top: 10px;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mkd-login-container .lines {
|
||||||
|
width: 200px;
|
||||||
|
border: 1px solid red;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mkd-login-container button[type="submit"] {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
#mkd-login-container .facebook-btn {
|
||||||
|
background-color: #3c589c;
|
||||||
|
}
|
||||||
|
#mkd-login-container .google-btn {
|
||||||
|
background-color: #df4b3b;
|
||||||
|
}
|
||||||
|
#mkd-login-container input {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 500px) {
|
||||||
|
#mkd-login-container {
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
#mkd-login-container .social-login {
|
||||||
|
width: 200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
#mkd-login-container .social-btn {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: 100;
|
||||||
|
color: white;
|
||||||
|
width: 200px;
|
||||||
|
height: 56px;
|
||||||
|
display: block;
|
||||||
|
line-height: 45px;
|
||||||
|
}
|
||||||
|
#mkd-login-container .social-btn:nth-child(1) {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
#mkd-login-container .social-btn span {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#mkd-login-container .facebook-btn:after {
|
||||||
|
content: "Facebook";
|
||||||
|
}
|
||||||
|
#mkd-login-container .google-btn:after {
|
||||||
|
content: "Google+";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background: #e9ecef;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
/* color: inherit; */
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
a:focus {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
padding: 15px 10px;
|
||||||
|
background: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-btn {
|
||||||
|
box-shadow: none;
|
||||||
|
outline: none !important;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line {
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
border-bottom: 1px dashed #ddd;
|
||||||
|
margin: 40px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
font-size: 12px;
|
||||||
|
display: block;
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar {
|
||||||
|
max-width: 250px;
|
||||||
|
width: 100%;
|
||||||
|
background: #151515;
|
||||||
|
color: #fff;
|
||||||
|
z-index: 2;
|
||||||
|
transition: all 0.3s;
|
||||||
|
-webkit-box-shadow: 2px 0px 4px 0px rgba(0, 0, 0, 0.75);
|
||||||
|
-moz-box-shadow: 2px 0px 4px 0px rgba(0, 0, 0, 0.75);
|
||||||
|
box-shadow: 2px 0px 4px 0px rgba(0, 0, 0, 0.75);
|
||||||
|
position: relative;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
#sidebar .sidebar-header {
|
||||||
|
padding: 20px;
|
||||||
|
background: #2c5ed6;
|
||||||
|
}
|
||||||
|
#sidebar ul.components {
|
||||||
|
padding: 0px 0px 20px 0px;
|
||||||
|
}
|
||||||
|
#sidebar ul p {
|
||||||
|
color: #fff;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
#sidebar ul li a {
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 1em;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
#sidebar ul li a:hover {
|
||||||
|
color: #151515;
|
||||||
|
background: #fff !important;
|
||||||
|
}
|
||||||
|
#sidebar ul li.active > a {
|
||||||
|
color: #fff;
|
||||||
|
background: #151515;
|
||||||
|
}
|
||||||
|
#sidebar a.active {
|
||||||
|
color: black;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar.active {
|
||||||
|
margin-left: -100%;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
a[aria-expanded="true"] {
|
||||||
|
color: #fff;
|
||||||
|
background: #151515;
|
||||||
|
}
|
||||||
|
|
||||||
|
a[data-toggle="collapse"] {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-toggle::after {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: 20px;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
ul ul a {
|
||||||
|
font-size: 0.9em !important;
|
||||||
|
padding-left: 30px !important;
|
||||||
|
background: #151515;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0px;
|
||||||
|
min-height: 100vh;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:focus,
|
||||||
|
.btn:active:focus,
|
||||||
|
.btn.active:focus {
|
||||||
|
outline: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
*:focus:not(a) {
|
||||||
|
outline: none;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#snackbar {
|
||||||
|
visibility: hidden;
|
||||||
|
/* Hidden by default. Visible on click */
|
||||||
|
min-width: 250px;
|
||||||
|
/* Set a default minimum width */
|
||||||
|
margin-left: -125px;
|
||||||
|
/* Divide value of min-width by 2 */
|
||||||
|
background-color: #333;
|
||||||
|
/* Black background color */
|
||||||
|
color: #fff;
|
||||||
|
/* White text color */
|
||||||
|
text-align: center;
|
||||||
|
/* Centered text */
|
||||||
|
border-radius: 2px;
|
||||||
|
/* Rounded borders */
|
||||||
|
padding: 16px;
|
||||||
|
/* Padding */
|
||||||
|
position: fixed;
|
||||||
|
/* Sit on top of the screen */
|
||||||
|
z-index: 1;
|
||||||
|
/* Add a z-index if needed */
|
||||||
|
left: 50%;
|
||||||
|
/* Center the snackbar */
|
||||||
|
bottom: 30px;
|
||||||
|
/* 30px from the bottom */
|
||||||
|
}
|
||||||
|
#snackbar .show {
|
||||||
|
visibility: visible;
|
||||||
|
/* Show the snackbar */
|
||||||
|
/* Add animation: Take 0.5 seconds to fade in and out the snackbar.
|
||||||
|
However, delay the fade out process for 2.5 seconds */
|
||||||
|
-webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s;
|
||||||
|
animation: fadein 0.5s, fadeout 0.5s 2.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes fadein {
|
||||||
|
from {
|
||||||
|
bottom: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
bottom: 30px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes fadein {
|
||||||
|
from {
|
||||||
|
bottom: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
bottom: 30px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-webkit-keyframes fadeout {
|
||||||
|
from {
|
||||||
|
bottom: 30px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
bottom: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes fadeout {
|
||||||
|
from {
|
||||||
|
bottom: 30px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
bottom: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
#sidebar {
|
||||||
|
margin-left: -250px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar.active {
|
||||||
|
margin-left: 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.modal-xl {
|
||||||
|
max-width: 1200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mkd-image-container {
|
||||||
|
max-width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mkd-upload-btn-wrapper {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 100px auto;
|
||||||
|
}
|
||||||
|
.mkd-upload-btn-wrapper input[type="file"] {
|
||||||
|
font-size: 100px;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
.mkd-upload-btn-wrapper .mkd-upload-btn {
|
||||||
|
border: 2px solid gray;
|
||||||
|
color: gray;
|
||||||
|
background-color: white;
|
||||||
|
padding: 8px 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mkd-upload-form-btn-wrapper {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.mkd-upload-form-btn-wrapper input[type="file"] {
|
||||||
|
font-size: 100px;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
/* .mkd-upload-form-btn-wrapper .mkd-upload-btn {
|
||||||
|
border: 2px solid gray;
|
||||||
|
color: gray;
|
||||||
|
background-color: white;
|
||||||
|
padding: 4px 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: bold; } */
|
||||||
|
|
||||||
|
#mkd-media-upload-container,
|
||||||
|
#mkd-media-crop-container {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mkd-media-panel-2,
|
||||||
|
.mkd-media-panel-3 {
|
||||||
|
display: none;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mkd-crop-upload-container-wrapper {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mkd-media-gallery-wrapper img {
|
||||||
|
-webkit-box-shadow: 0px 0px 14px 0px rgba(0, 0, 0, 0.75);
|
||||||
|
-moz-box-shadow: 0px 0px 14px 0px rgba(0, 0, 0, 0.75);
|
||||||
|
box-shadow: 0px 0px 14px 0px rgba(0, 0, 0, 0.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mkd-gallery-image-image:hover {
|
||||||
|
outline: 5px dotted black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mkd-gallery-image-image.active {
|
||||||
|
outline: 5px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mkd-choose-image {
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group img {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.croppie-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.croppie-container .cr-image {
|
||||||
|
z-index: -1;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
transform-origin: 0 0;
|
||||||
|
max-height: none;
|
||||||
|
max-width: none;
|
||||||
|
-webkit-transform: translateZ(0);
|
||||||
|
-moz-transform: translateZ(0);
|
||||||
|
-ms-transform: translateZ(0);
|
||||||
|
transform: translateZ(0);
|
||||||
|
}
|
||||||
|
.croppie-container .cr-boundary {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 0 auto;
|
||||||
|
z-index: 1;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.croppie-container .cr-viewport {
|
||||||
|
position: absolute;
|
||||||
|
border: 2px solid #fff;
|
||||||
|
margin: auto;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
box-shadow: 0 0 2000px 2000px rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 0;
|
||||||
|
-webkit-transform: translateZ(0);
|
||||||
|
-moz-transform: translateZ(0);
|
||||||
|
-ms-transform: translateZ(0);
|
||||||
|
transform: translateZ(0);
|
||||||
|
}
|
||||||
|
.croppie-container .cr-resizer {
|
||||||
|
position: absolute;
|
||||||
|
border: 2px solid #fff;
|
||||||
|
margin: auto;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
box-shadow: 0 0 2000px 2000px rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 0;
|
||||||
|
z-index: 2;
|
||||||
|
box-shadow: none;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.croppie-container .cr-resizer-vertical {
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: all;
|
||||||
|
bottom: -5px;
|
||||||
|
cursor: row-resize;
|
||||||
|
width: 100%;
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
.croppie-container .cr-resizer-vertical::after {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px solid black;
|
||||||
|
background: #fff;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
content: "";
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -5px;
|
||||||
|
}
|
||||||
|
.croppie-container .cr-resizer-horisontal {
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: all;
|
||||||
|
right: -5px;
|
||||||
|
cursor: col-resize;
|
||||||
|
width: 10px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.croppie-container .cr-resizer-horisontal::after {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px solid black;
|
||||||
|
background: #fff;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
content: "";
|
||||||
|
top: 50%;
|
||||||
|
margin-top: -5px;
|
||||||
|
}
|
||||||
|
.croppie-container .cr-original-image {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.croppie-container .cr-vp-circle {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.croppie-container .cr-overlay {
|
||||||
|
z-index: 1;
|
||||||
|
position: absolute;
|
||||||
|
cursor: move;
|
||||||
|
touch-action: none;
|
||||||
|
-webkit-transform: translateZ(0);
|
||||||
|
-moz-transform: translateZ(0);
|
||||||
|
-ms-transform: translateZ(0);
|
||||||
|
transform: translateZ(0);
|
||||||
|
}
|
||||||
|
.croppie-container .cr-slider-wrap {
|
||||||
|
width: 75%;
|
||||||
|
margin: 15px auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.croppie-result {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.croppie-result img {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cr-slider {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
width: 300px;
|
||||||
|
max-width: 100%;
|
||||||
|
padding-top: 8px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.cr-slider::-webkit-slider-runnable-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 3px;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
border: 0;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.cr-slider::-webkit-slider-thumb {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
border: none;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #ddd;
|
||||||
|
margin-top: -6px;
|
||||||
|
}
|
||||||
|
.cr-slider:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.cr-slider:focus::-ms-fill-lower {
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
.cr-slider:focus::-ms-fill-upper {
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
.cr-slider::-moz-range-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 3px;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
border: 0;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.cr-slider::-moz-range-thumb {
|
||||||
|
border: none;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #ddd;
|
||||||
|
margin-top: -6px;
|
||||||
|
}
|
||||||
|
.cr-slider:-moz-focusring {
|
||||||
|
outline: 1px solid white;
|
||||||
|
outline-offset: -1px;
|
||||||
|
}
|
||||||
|
.cr-slider::-ms-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 5px;
|
||||||
|
background: transparent;
|
||||||
|
border-color: transparent;
|
||||||
|
border-width: 6px 0;
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
.cr-slider::-ms-fill-lower {
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.cr-slider::-ms-fill-upper {
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.cr-slider::-ms-thumb {
|
||||||
|
border: none;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #ddd;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cr-rotate-controls {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 5px;
|
||||||
|
left: 5px;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.cr-rotate-controls button {
|
||||||
|
border: 0;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
.cr-rotate-controls i:before {
|
||||||
|
display: inline-block;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cr-rotate-l i:before {
|
||||||
|
content: "↺";
|
||||||
|
}
|
||||||
|
|
||||||
|
.cr-rotate-r i:before {
|
||||||
|
content: "↻";
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul.collapse li a {
|
||||||
|
background-color: #3e3f40;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table .thead-light th:first-child,
|
||||||
|
table .tbody-light td:first-child {
|
||||||
|
border-left: 1px solid #dee2e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table .thead-light th:last-child,
|
||||||
|
table .tbody-light td:last-child {
|
||||||
|
border-right: 1px solid #dee2e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table .tbody-light tr:last-child {
|
||||||
|
border-bottom: 1px solid #dee2e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb-link {
|
||||||
|
color: #2c549c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navigation-row {
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px 20px 20px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-underline {
|
||||||
|
text-decoration: underline !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-light {
|
||||||
|
background-color: white;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.form-container-auth {
|
||||||
|
max-width: 30rem;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-wrapper {
|
||||||
|
margin-top: 10vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hamburger {
|
||||||
|
position: absolute;
|
||||||
|
right: -48px;
|
||||||
|
top: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-group-item-action:hover,
|
||||||
|
.list-group-item-action:active,
|
||||||
|
.custom-list-item.active.collapsed {
|
||||||
|
color: #151515;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
.custom-list-item.active {
|
||||||
|
background-color: transparent;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-list-item {
|
||||||
|
height: 50px;
|
||||||
|
background-color: transparent;
|
||||||
|
color: white;
|
||||||
|
padding: 0 10px;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
#sidebar .card {
|
||||||
|
border: none;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
#sidebar .card-header {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
#sidebar .card-header:first-child {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
.dropdownMenuItem {
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.menu-active {
|
||||||
|
background-color: white;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#body {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modal-image-slot {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bulkDeleteButton,
|
||||||
|
#bulkEditButton {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* required field red asterisk */
|
||||||
|
.form-group.required .control-label:after {
|
||||||
|
color: red;
|
||||||
|
content: "*";
|
||||||
|
margin-left: 5px;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-body {
|
||||||
|
height: 100%;
|
||||||
|
min-height: 100vh;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
overflow: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.google-button,
|
||||||
|
.facebook-button {
|
||||||
|
height: 50px;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.facebook-button {
|
||||||
|
background-color: #3b5998;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flash-response {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.hide-answer-select,
|
||||||
|
.answer-value,
|
||||||
|
.answer-image {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.hide-answer-select.show,
|
||||||
|
.answer-value.show,
|
||||||
|
.answer-image.show {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-arrows {
|
||||||
|
width: 20px;
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: -3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weight-active-score.has-value {
|
||||||
|
outline: blue 1px solid;
|
||||||
|
}
|
||||||
|
.custom-picker {
|
||||||
|
border: 1px solid #ced4da;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-flash-message {
|
||||||
|
color: black;
|
||||||
|
width: 80%;
|
||||||
|
max-width: 700px;
|
||||||
|
padding: 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
|
||||||
|
position: fixed;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
background-color: white;
|
||||||
|
transform: translateX(1000%);
|
||||||
|
transition: 300ms all cubic-bezier(0.165, 0.84, 0.44, 1);
|
||||||
|
}
|
||||||
|
.custom-flash-message.show {
|
||||||
|
z-index: 1051;
|
||||||
|
transform: translateX(0%);
|
||||||
|
transition: 300ms all cubic-bezier(0.165, 0.84, 0.44, 1);
|
||||||
|
}
|
||||||
|
.custom-flash-message.show.success {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
.custom-flash-message.show.error {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
@media only screen and (max-height: 580px) {
|
||||||
|
#page1 .secondRow {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media only screen and (max-width: 992px) {
|
||||||
|
#page1 .main-image-container {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#page1 .columns {
|
||||||
|
width: 100%;
|
||||||
|
margin-left: 0;
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
#page1 .firstRow {
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
#page1 .secondRow {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
#page1 .secondRow .heading {
|
||||||
|
font-size: 40px;
|
||||||
|
margin-bottom: 48px;
|
||||||
|
}
|
||||||
|
#page1 .secondRow .para {
|
||||||
|
margin-bottom: 56px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
#page1 .secondRow .beginButton {
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
#page2 h4 {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
#page2 h1 {
|
||||||
|
font-size: 36px;
|
||||||
|
}
|
||||||
|
.progressBar .progressColumns p {
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
#page3 .questionRow h1 {
|
||||||
|
font-size: 36px;
|
||||||
|
line-height: 56px;
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
.answerInner.typeText input,
|
||||||
|
.answerInner.typeNum input {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
#page4 .createdByDiv,
|
||||||
|
.createdByDiv {
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
.noteRow {
|
||||||
|
margin-bottom: 10vh;
|
||||||
|
}
|
||||||
|
#page3 .questionRow.mtb {
|
||||||
|
padding: 24px 0;
|
||||||
|
}
|
||||||
|
#page3 .noteRow {
|
||||||
|
flex-direction: column;
|
||||||
|
margin-bottom: 10vh;
|
||||||
|
}
|
||||||
|
#page3 .noteRow .noteTitle {
|
||||||
|
border: 1px solid #101010 !important;
|
||||||
|
border-top: none !important;
|
||||||
|
}
|
||||||
|
#page3 .noteRow .noteTitle h4 {
|
||||||
|
font-size: 12px;
|
||||||
|
margin: 8px 0;
|
||||||
|
}
|
||||||
|
#page3 .noteRow .noteDesc {
|
||||||
|
border: 1px solid #101010 !important;
|
||||||
|
border-top: none !important;
|
||||||
|
}
|
||||||
|
#page3 .noteRow .noteDesc p {
|
||||||
|
margin: 8px 0;
|
||||||
|
font-size: 13px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.multiBtns {
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 14px 10px;
|
||||||
|
}
|
||||||
|
#page3 .noteRow.image-below {
|
||||||
|
margin-bottom: 5vh !important;
|
||||||
|
}
|
||||||
|
#page3 .questionRow.mtb.no-note {
|
||||||
|
margin-bottom: 8vh !important;
|
||||||
|
}
|
||||||
|
#page3 .questionRow.mtb.no-note.no-image {
|
||||||
|
margin-bottom: 16vh !important;
|
||||||
|
}
|
||||||
|
#page3 .answerRow {
|
||||||
|
margin-top: 24px;
|
||||||
|
}
|
||||||
|
#page4 .headerRow,
|
||||||
|
.headerRow {
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
.sliderDiv {
|
||||||
|
margin: 32px auto 8px auto;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
#typeGeo .answerInner input {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
#weatherApi .header {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#page5 .responseRow .responseInner .responseBody p {
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
.control-arrows img {
|
||||||
|
width: 15px;
|
||||||
|
}
|
||||||
|
.sliderRanges .ranges {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
#page5 .responseRow .responseInner .responseHead h1 {
|
||||||
|
font-size: 36px;
|
||||||
|
}
|
||||||
|
#page5 .responseRow .responseInner .responseBody p {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 17 KiB |