working on droplet, adding app components
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@@ -4,4 +4,9 @@ node_modules
|
|||||||
.env
|
.env
|
||||||
|
|
||||||
db/db.json
|
db/db.json
|
||||||
ui/_/code/env.js
|
ui/_/code/env.js
|
||||||
|
apps/*
|
||||||
|
|
||||||
|
csv.csv
|
||||||
|
csv.js
|
||||||
|
csv.json
|
||||||
@@ -5,6 +5,9 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node server/index.js"
|
"start": "node server/index.js"
|
||||||
},
|
},
|
||||||
|
"workspaces": [
|
||||||
|
"apps/*"
|
||||||
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"argon2": "^0.44.0",
|
"argon2": "^0.44.0",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
|
|||||||
@@ -17,12 +17,14 @@ import Database from "./db/db.js"
|
|||||||
import AuthHandler from './auth.js';
|
import AuthHandler from './auth.js';
|
||||||
import PaymentsHandler from "./payments.js"
|
import PaymentsHandler from "./payments.js"
|
||||||
|
|
||||||
|
import parchment from '../apps/parchment/index.js';
|
||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
db;
|
db;
|
||||||
auth;
|
auth;
|
||||||
UIPath = path.join(__dirname, '../ui')
|
UIPath = path.join(__dirname, '../ui')
|
||||||
DBPath = path.join(__dirname, '../db')
|
DBPath = path.join(__dirname, '../db')
|
||||||
ComalPath = path.join(os.homedir(), 'Sites/comalyr.com')
|
ComalPath = path.join(os.homedir(), 'comalyr.com')
|
||||||
|
|
||||||
registerRoutes(router) {
|
registerRoutes(router) {
|
||||||
/* Stripe */
|
/* Stripe */
|
||||||
@@ -75,7 +77,7 @@ class Server {
|
|||||||
const contact = contactRaw.trim() ? JSON.parse(contactRaw) : [];
|
const contact = contactRaw.trim() ? JSON.parse(contactRaw) : [];
|
||||||
const members = db.members.getByNetwork(networkId)
|
const members = db.members.getByNetwork(networkId)
|
||||||
let stripeMembers = await payments.getCustomers(networkId)
|
let stripeMembers = await payments.getCustomers(networkId)
|
||||||
console.log("stripemenbers: ", stripeMembers)
|
// console.log("stripemenbers: ", stripeMembers)
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
join,
|
join,
|
||||||
@@ -263,6 +265,8 @@ class Server {
|
|||||||
app.use(this.logRequest);
|
app.use(this.logRequest);
|
||||||
app.use(this.logResponse);
|
app.use(this.logResponse);
|
||||||
|
|
||||||
|
app.use('/apps/parchment', parchment.app);
|
||||||
|
|
||||||
let router = express.Router();
|
let router = express.Router();
|
||||||
this.registerRoutes(router)
|
this.registerRoutes(router)
|
||||||
app.use('/', router);
|
app.use('/', router);
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ export default class PaymentsHandler {
|
|||||||
{ limit: 100, expand: ['data.subscriptions'] },
|
{ limit: 100, expand: ['data.subscriptions'] },
|
||||||
{ stripeAccount: network.stripeAccountId }
|
{ stripeAccount: network.stripeAccountId }
|
||||||
);
|
);
|
||||||
console.log(customers)
|
|
||||||
|
|
||||||
return customers.data.map(customer => ({
|
return customers.data.map(customer => ({
|
||||||
id: customer.id,
|
id: customer.id,
|
||||||
|
|||||||
56
serveradmin.md
Normal file
56
serveradmin.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# ssh
|
||||||
|
ssh root@167.172.247.123
|
||||||
|
|
||||||
|
# certs
|
||||||
|
certbot --nginx -d comalyr.com -d ...
|
||||||
|
|
||||||
|
# Code Server
|
||||||
|
curl -fsSL https://code-server.dev/install.sh | sh
|
||||||
|
pm2 start code-server --name code
|
||||||
|
cat ~/.config/code-server/config.yaml
|
||||||
|
|
||||||
|
# pm2
|
||||||
|
## For Running the Servers
|
||||||
|
|
||||||
|
## start your app
|
||||||
|
pm2 start "npm run start" --name comalyr
|
||||||
|
|
||||||
|
## see running processes
|
||||||
|
pm2 list
|
||||||
|
|
||||||
|
## view logs
|
||||||
|
pm2 logs
|
||||||
|
pm2 logs comalyr
|
||||||
|
|
||||||
|
## restart
|
||||||
|
pm2 restart comalyr
|
||||||
|
|
||||||
|
## stop
|
||||||
|
pm2 stop comalyr
|
||||||
|
|
||||||
|
## save all current processes to be run on startup
|
||||||
|
pm2 save
|
||||||
|
|
||||||
|
# nginx
|
||||||
|
|
||||||
|
tail -f /var/log/nginx/access.log
|
||||||
|
tail -f /var/log/nginx/error.log
|
||||||
|
cat /var/log/nginx/access.log
|
||||||
|
|
||||||
|
## list config
|
||||||
|
cat /etc/nginx/sites-available/norn
|
||||||
|
nano /etc/nginx/sites-available/norn
|
||||||
|
|
||||||
|
## restart
|
||||||
|
systemctl restart nginx
|
||||||
|
|
||||||
|
# Postgres
|
||||||
|
|
||||||
|
systemctl status postgresql
|
||||||
|
|
||||||
|
# debugging
|
||||||
|
|
||||||
|
curl http://localhost:8080
|
||||||
|
|
||||||
|
curl -v https://comalyr.com 2>&1 | head -30
|
||||||
|
this will list out the process of connecting
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
--quillred: #DE3F3F;
|
--quillred: #DE3F3F;
|
||||||
--brown: #812A18;
|
--brown: #812A18;
|
||||||
--darkbrown: #3f0808;
|
--darkbrown: #3f0808;
|
||||||
|
--divider: rgb(223 201 169);
|
||||||
|
|
||||||
--house-src: /_/icons/house.svg;
|
--house-src: /_/icons/house.svg;
|
||||||
--nodes-src: /_/icons/nodes.svg;
|
--nodes-src: /_/icons/nodes.svg;
|
||||||
@@ -39,9 +40,10 @@
|
|||||||
:root.dark {
|
:root.dark {
|
||||||
--main: #000000;
|
--main: #000000;
|
||||||
--app: #180404;
|
--app: #180404;
|
||||||
--accent: #8a7454;
|
--accent: #935757;
|
||||||
--accent2: var(--gold);
|
--accent2: var(--gold);
|
||||||
--window: #340f0f;
|
--window: #340f0f;
|
||||||
|
--divider: rgb(69 34 34);
|
||||||
|
|
||||||
--house-src: /_/icons/housedark.svg;
|
--house-src: /_/icons/housedark.svg;
|
||||||
--nodes-src: /_/icons/nodesdark.svg;
|
--nodes-src: /_/icons/nodesdark.svg;
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ class Dashboard extends Shadow {
|
|||||||
.gap(8);
|
.gap(8);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
.gap(0.5, em)
|
||||||
.paddingTop(4, pct)
|
.paddingTop(4, pct)
|
||||||
.paddingLeft(5, pct)
|
.paddingLeft(5, pct)
|
||||||
.width(100, pct)
|
.width(100, pct)
|
||||||
|
|||||||
203
ui/desktop/apps/Dashboard/alt.js
Normal file
203
ui/desktop/apps/Dashboard/alt.js
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
class Dashboard extends Shadow {
|
||||||
|
|
||||||
|
gridStyle() {
|
||||||
|
return {
|
||||||
|
table: {
|
||||||
|
'background-color': 'var(--window)',
|
||||||
|
'color': 'var(--accent)',
|
||||||
|
'box-shadow': 'none',
|
||||||
|
'font-size': '0.9em',
|
||||||
|
'max-width': '90%'
|
||||||
|
},
|
||||||
|
th: {
|
||||||
|
'background-color': 'var(--window)',
|
||||||
|
'color': 'var(--accent)',
|
||||||
|
'border': 'none',
|
||||||
|
'border-bottom': '1px solid var(--divider)'
|
||||||
|
},
|
||||||
|
td: {
|
||||||
|
'background-color': 'var(--window)',
|
||||||
|
'color': 'var(--accent)',
|
||||||
|
'border': 'none',
|
||||||
|
'border-bottom': '1px solid var(--divider)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gridCSS() {
|
||||||
|
css(`
|
||||||
|
input.gridjs-input {
|
||||||
|
background-color: var(--window);
|
||||||
|
color: var(--accent);
|
||||||
|
border: none;
|
||||||
|
border-bottom: 1px solid var(--divider);
|
||||||
|
border-radius: 0;
|
||||||
|
margin-left: 5em
|
||||||
|
}
|
||||||
|
|
||||||
|
.gridjs-wrapper {
|
||||||
|
box-shadow: none;
|
||||||
|
padding-left: 4em;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
VStack(() => {
|
||||||
|
|
||||||
|
if(window.location.pathname.startsWith("/my")) {
|
||||||
|
h1(global.profile.name);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else if(!window.location.pathname.includes("comalyr")) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
h1("Website Inquiries")
|
||||||
|
.paddingLeft(5, pct)
|
||||||
|
|
||||||
|
VStack(() => {
|
||||||
|
VStack(() => {
|
||||||
|
p("Contact Us")
|
||||||
|
.marginBottom(2, vh)
|
||||||
|
.marginLeft(5, em)
|
||||||
|
.fontStyle("italic")
|
||||||
|
|
||||||
|
ZStack(() => {
|
||||||
|
new gridjs.Grid({
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: "Time",
|
||||||
|
sort: {
|
||||||
|
compare: (a, b) => {
|
||||||
|
const parse = (str) => {
|
||||||
|
const [datePart, timePart] = str.trim().split(/\s+/);
|
||||||
|
const [month, day, year] = datePart.split('.');
|
||||||
|
const normalized = timePart.replace(/(\d+):(\d+)(am|pm)/i, (_, h, m, meridiem) => {
|
||||||
|
let hours = parseInt(h);
|
||||||
|
if (meridiem.toLowerCase() === 'pm' && hours !== 12) hours += 12;
|
||||||
|
if (meridiem.toLowerCase() === 'am' && hours === 12) hours = 0;
|
||||||
|
return `${String(hours).padStart(2, '0')}:${m}:00`;
|
||||||
|
});
|
||||||
|
return new Date(`${year}-${month}-${day}T${normalized}`);
|
||||||
|
}
|
||||||
|
return parse(a) - parse(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"First", "Last", "Email", "Phone",
|
||||||
|
{
|
||||||
|
name: "Message",
|
||||||
|
formatter: (cell) => gridjs.html(`
|
||||||
|
<div class="messageCell" style="
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 1;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
max-width: 300px;
|
||||||
|
" data-message="${cell.replace(/"/g, '"')}">
|
||||||
|
${cell}
|
||||||
|
</div>
|
||||||
|
`)
|
||||||
|
},
|
||||||
|
"County"
|
||||||
|
],
|
||||||
|
data: global.currentNetwork.data.contact.map(e => [
|
||||||
|
e.time.replace(/:\d{6}(?=am|pm)/i, '')
|
||||||
|
.replace('-', ' ')
|
||||||
|
.replace(/(\d{1,2}:\d{2})(am|pm)/i, (_, time, meridiem) => {
|
||||||
|
const [h, m] = time.split(':');
|
||||||
|
return `${h.padStart(2, '0')}:${m}${meridiem.toLowerCase()}`;
|
||||||
|
}),
|
||||||
|
e.fname,
|
||||||
|
e.lname,
|
||||||
|
e.email,
|
||||||
|
e.phone,
|
||||||
|
e.message,
|
||||||
|
e.county ?? "Not Specified"
|
||||||
|
]),
|
||||||
|
sort: {
|
||||||
|
multiColumn: false,
|
||||||
|
initialState: {
|
||||||
|
columnIndex: 0,
|
||||||
|
direction: "desc"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
search: true,
|
||||||
|
style: this.gridStyle()
|
||||||
|
}).render(quill.rendering.last)
|
||||||
|
|
||||||
|
this.gridCSS()
|
||||||
|
})
|
||||||
|
.overflow("hidden")
|
||||||
|
})
|
||||||
|
.gap(0.5, em)
|
||||||
|
|
||||||
|
VStack(() => {
|
||||||
|
p("Join")
|
||||||
|
.marginBottom(2, vh)
|
||||||
|
.marginLeft(5, em)
|
||||||
|
.fontStyle("italic")
|
||||||
|
|
||||||
|
ZStack(() => {
|
||||||
|
new gridjs.Grid({
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: "Time",
|
||||||
|
sort: {
|
||||||
|
compare: (a, b) => {
|
||||||
|
const parse = (str) => {
|
||||||
|
const [datePart, timePart] = str.trim().split(/\s+/);
|
||||||
|
const [month, day, year] = datePart.split('.');
|
||||||
|
const normalized = timePart.replace(/(\d+):(\d+)(am|pm)/i, (_, h, m, meridiem) => {
|
||||||
|
let hours = parseInt(h);
|
||||||
|
if (meridiem.toLowerCase() === 'pm' && hours !== 12) hours += 12;
|
||||||
|
if (meridiem.toLowerCase() === 'am' && hours === 12) hours = 0;
|
||||||
|
return `${String(hours).padStart(2, '0')}:${m}:00`;
|
||||||
|
});
|
||||||
|
return new Date(`${year}-${month}-${day}T${normalized}`);
|
||||||
|
}
|
||||||
|
return parse(a) - parse(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"First", "Last", "Email", "Phone", "County"
|
||||||
|
],
|
||||||
|
data: global.currentNetwork.data.join.map(e => [
|
||||||
|
e.time.replace(/:\d{6}(?=am|pm)/i, '')
|
||||||
|
.replace('-', ' ')
|
||||||
|
.replace(/(\d{1,2}:\d{2})(am|pm)/i, (_, time, meridiem) => {
|
||||||
|
const [h, m] = time.split(':');
|
||||||
|
return `${h.padStart(2, '0')}:${m}${meridiem.toLowerCase()}`;
|
||||||
|
}),
|
||||||
|
e.fname,
|
||||||
|
e.lname,
|
||||||
|
e.email,
|
||||||
|
e.phone,
|
||||||
|
e.county ?? "Not Specified"
|
||||||
|
]),
|
||||||
|
sort: true,
|
||||||
|
search: true,
|
||||||
|
style: this.gridStyle()
|
||||||
|
}).render(quill.rendering.last)
|
||||||
|
|
||||||
|
this.gridCSS()
|
||||||
|
})
|
||||||
|
.marginBottom(3, em)
|
||||||
|
.overflow("hidden")
|
||||||
|
})
|
||||||
|
.gap(0.5, em)
|
||||||
|
})
|
||||||
|
.gap(4, em)
|
||||||
|
})
|
||||||
|
.gap(0.5, em)
|
||||||
|
.paddingTop(4, pct)
|
||||||
|
.width(100, pct)
|
||||||
|
.height(100, pct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
register(Dashboard)
|
||||||
@@ -4,13 +4,13 @@ class People extends Shadow {
|
|||||||
h1("Members")
|
h1("Members")
|
||||||
.fontWeight("bold")
|
.fontWeight("bold")
|
||||||
.marginBottom(2, em)
|
.marginBottom(2, em)
|
||||||
.marginLeft(4, em)
|
.marginLeft(2, em)
|
||||||
|
|
||||||
VStack(() => {
|
VStack(() => {
|
||||||
VStack(() => {
|
VStack(() => {
|
||||||
p("Officers")
|
p("Officers")
|
||||||
.marginBottom(2, vh)
|
.marginBottom(2, vh)
|
||||||
.marginLeft(8, em)
|
.marginLeft(4, em)
|
||||||
.fontStyle("italic")
|
.fontStyle("italic")
|
||||||
|
|
||||||
ZStack(() => {
|
ZStack(() => {
|
||||||
@@ -27,35 +27,36 @@ class People extends Shadow {
|
|||||||
'background-color': 'var(--window)',
|
'background-color': 'var(--window)',
|
||||||
'color': 'var(--accent)',
|
'color': 'var(--accent)',
|
||||||
'box-shadow': 'none',
|
'box-shadow': 'none',
|
||||||
'font-size': '0.9em'
|
'font-size': '0.9em',
|
||||||
|
'max-width': '90%'
|
||||||
},
|
},
|
||||||
th: {
|
th: {
|
||||||
'background-color': 'var(--window)',
|
'background-color': 'var(--window)',
|
||||||
'color': 'var(--accent)',
|
'color': 'var(--accent)',
|
||||||
'border': 'none',
|
'border': 'none',
|
||||||
'border-bottom': '1px solid rgb(69 53 53)'
|
|
||||||
},
|
},
|
||||||
td: {
|
td: {
|
||||||
'background-color': 'var(--window)',
|
'background-color': 'var(--window)',
|
||||||
'color': 'var(--accent)',
|
'color': 'var(--accent)',
|
||||||
'border': 'none',
|
'border': 'none',
|
||||||
'border-bottom': '1px solid rgb(69 53 53)'
|
'border-bottom': '1px solid var(--divider)'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).render(quill.rendering.last)
|
}).render(quill.rendering.last)
|
||||||
})
|
})
|
||||||
|
.overflow("hidden")
|
||||||
})
|
})
|
||||||
.gap(0.5, em)
|
.gap(0.5, em)
|
||||||
|
|
||||||
VStack(() => {
|
VStack(() => {
|
||||||
p("Stripe Subscribers")
|
p("Stripe Subscribers")
|
||||||
.marginBottom(2, vh)
|
.marginBottom(2, vh)
|
||||||
.marginLeft(8, em)
|
.marginLeft(4, em)
|
||||||
.fontStyle("italic")
|
.fontStyle("italic")
|
||||||
|
|
||||||
ZStack(() => {
|
ZStack(() => {
|
||||||
new gridjs.Grid({
|
new gridjs.Grid({
|
||||||
columns: ["Amount", "Name", "Email", "Phone", "Area", "Created"],
|
columns: ["Amount", "Name", "Email", "Phone", "County", "Created"],
|
||||||
data: global.currentNetwork.data.stripeMembers.map(m => [
|
data: global.currentNetwork.data.stripeMembers.map(m => [
|
||||||
"$" + m.subscriptions[0].amount,
|
"$" + m.subscriptions[0].amount,
|
||||||
m.name,
|
m.name,
|
||||||
@@ -81,19 +82,19 @@ class People extends Shadow {
|
|||||||
'background-color': 'var(--window)',
|
'background-color': 'var(--window)',
|
||||||
'color': 'var(--accent)',
|
'color': 'var(--accent)',
|
||||||
'box-shadow': 'none',
|
'box-shadow': 'none',
|
||||||
'font-size': '0.9em'
|
'font-size': '0.9em',
|
||||||
|
'max-width': '90%'
|
||||||
},
|
},
|
||||||
th: {
|
th: {
|
||||||
'background-color': 'var(--window)',
|
'background-color': 'var(--window)',
|
||||||
'color': 'var(--accent)',
|
'color': 'var(--accent)',
|
||||||
'border': 'none',
|
'border': 'none',
|
||||||
'border-bottom': '1px solid rgb(69 53 53)'
|
|
||||||
},
|
},
|
||||||
td: {
|
td: {
|
||||||
'background-color': 'var(--window)',
|
'background-color': 'var(--window)',
|
||||||
'color': 'var(--accent)',
|
'color': 'var(--accent)',
|
||||||
'border': 'none',
|
'border': 'none',
|
||||||
'border-bottom': '1px solid rgb(69 53 53)'
|
'border-bottom': '1px solid var(--divider)'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).render(quill.rendering.last)
|
}).render(quill.rendering.last)
|
||||||
@@ -103,17 +104,18 @@ class People extends Shadow {
|
|||||||
background-color: var(--window);
|
background-color: var(--window);
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
border: none;
|
border: none;
|
||||||
border-bottom: 1px solid rgb(69 53 53);
|
border-bottom: 1px solid var(--divider);
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
margin-left: 8em
|
margin-left: 4em
|
||||||
}
|
}
|
||||||
|
|
||||||
.gridjs-wrapper {
|
.gridjs-wrapper {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
padding-left: 8em;
|
padding-left: 3em;
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
.marginBottom(3, em)
|
||||||
})
|
})
|
||||||
.gap(0.5, em)
|
.gap(0.5, em)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -33,6 +33,16 @@ class AppWindow extends Shadow {
|
|||||||
case "Settings":
|
case "Settings":
|
||||||
Settings()
|
Settings()
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
this.innerHTML = `
|
||||||
|
<iframe
|
||||||
|
src="/apps/parchment"
|
||||||
|
sandbox="allow-scripts allow-same-origin allow-forms"
|
||||||
|
width="100%"
|
||||||
|
height="100%"
|
||||||
|
>
|
||||||
|
</iframe>
|
||||||
|
`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.overflow("scroll")
|
.overflow("scroll")
|
||||||
|
|||||||
Reference in New Issue
Block a user